Ruby - 将方法作为回调传递给 DLL 库
Posted
技术标签:
【中文标题】Ruby - 将方法作为回调传递给 DLL 库【英文标题】:Ruby - passing a method to a DLL library as a callback 【发布时间】:2015-03-02 21:16:42 【问题描述】:假设我有一个带有此函数的 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 消息框并将结果传递给回调函数。
问题是:是否可以通过 Fiddle 或类似的方式在 Ruby 中使用此函数,并以某种方式将 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 函数?
【问题讨论】:
可能相关:***.com/questions/3327666/… 该链接描述了如何使用 Ruby 调用需要回调的 API 函数。因此,您可能可以将其用作指南。 测试包括aqsort()
example。也看看Fiddle::Importer#bind
。
感谢您提供的 qsort() 示例! Fiddle::Closure 似乎是回调的正确选择:)
【参考方案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)
我真的不知道它是如何工作的 - 但它工作正常。
【讨论】:
【参考方案2】:另一种语法是使用 Fiddle 的 BlockCaller
:
myClosure = Fiddle::Closure::BlockCaller.new(Fiddle::TYPE_VOID, [Fiddle::TYPE_INT]) do |value|
puts "MessageBox result is #value"
end
【讨论】:
以上是关于Ruby - 将方法作为回调传递给 DLL 库的主要内容,如果未能解决你的问题,请参考以下文章