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

时间:2015-03-02 21:16:43

标签: c++ c ruby dll

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

#include <Windows.h>

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函数?

1 个答案:

答案 0 :(得分:1)

所以我找到了解决方案:

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)

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