Ruby – 将方法作为回调传递给DLL库

假设我有一个带有此函数的C / C ++库,编译为DLL:

#include  extern "C" __declspec(dllexport) void __stdcall myFunction(void (*myCallback)(int)) { int result = MessageBox( 0, (LPCWSTR)L"Press yes or no", (LPCWSTR)L"Test", MB_YESNO ); myCallback(result); } 

它只是打开标准的Win32消息框并将结果传递给回调函数。

问题是:是否可以在Ruby中使用此函数,通过Fiddle或类似的东西,并以某种方式将Ruby方法传递给它,以便从C ++代码中调用它?

这是我用来将DLL库导入Ruby的代码:

 require "fiddle" myLibrary = Fiddle.dlopen("myLibrary.dll") myFunction = Fiddle::Function.new( myLibrary["myFunction"], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOID ) def myCallback(value) puts "MessageBox result is #{value}" end 

这显然不起作用:

 myFunction.call(method(:myCallback)) 

它只是抛出一个TypeError – 无法将Method转换为Integer。

有没有办法将回调传递给C函数?

所以我找到了解决方案:

 myClosure = Class.new(Fiddle::Closure) { def call(value) puts "MessageBox result is #{value}" end }.new(Fiddle::TYPE_VOID, [Fiddle::TYPE_INT]) 

然后我可以简单地调用C函数:

 myFunction.call(myClosure) 

我真的不知道它是如何工作的 – 但它工作正常。