赞 | 0 |
VIP | 2 |
好人卡 | 27 |
积分 | 1 |
经验 | 26327 |
最后登录 | 2019-10-13 |
在线时间 | 953 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 110
- 在线时间
- 953 小时
- 注册时间
- 2007-4-25
- 帖子
- 805
|
你这个是 C++ 问题啊。Ruby 标准库中只提供了调用外部 C 函数的接口(dl、Win32API 这两个库),没有提供 C++ 的绑定,因为前者是跨编译器的,而后者的协议依赖于具体的 C++ 实现(MSVC?MinGW?GCC?TCC?Borland C++?)和平台。后者的绑定过程相对于 C 函数来说也比较复杂——当 C++ 类包含虚函数时,调用端需要自行访问虚表处理多态绑定;成员函数的 __thiscall 调用约定需要特殊处理;编译器特定的函数名称装饰也需要特殊处理。这些都不能通过默认的 dl 或是 Win32API 库来处理,RM 默认只有 Win32API,所以也不能处理。在一个自由的 Ruby 环境下,用户可以通过写 Ruby 扩展来自行建立一个可以绑定 C++ 类、函数的机制,但这个在(默认情况下)没有导出 Ruby API 的 RM 中无法实现。RM 中唯一可行的方案就是通过中间语言 C 做桥,在 C++ 层上另建一层 Ruby 可识别的 C 接口,然后再用 Win32API 调用。如果是静态绑定的 C++ 函数,那就可以只是简单的 wrapper,将 C++ 的接口协议改写为 C 的协议 [1];但一旦需要处理多态时,由于需要查询虚表查进行函数分派,即便实现了也是与特定版本的编译器绑在了一起,没有可移植性。这时最好是直接封装了你想要实现的功能,即实现一个高层接口。当然,你可以实现一个 C 接口调用 dynamic_cast 或者 typeid 在运行时判断动态类型,这个的效率自然比直接查询虚表低。
比如FrameFunc这是一个函数,这样在ruby中如何使用?
你可以在 RM 映射了导出 FrameFunc 这个函数的 DLL 之后调用 GetProcAddress 获取 FrameFunc 的地址,前提是 FrameFunc 确实被导出了。否则的话,你可以在 DLL 里建一个接口返回这个函数的地址,然后作为 32 位整数传给 Ruby。
[1] 比如,Klass::System_SetState(int, const char*) 这个成员函数的签名可以被改写为 System_SetState(Klass*, int, const char*),并按 C 函数 __stdcall 约定导出。 |
|