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)
我真的不知道它是如何工作的 – 但它工作正常。