我和Luabind有一个问题,我不知道如何在没有一些过于简化的解决方案的情况下进行修复。
Luabind似乎只允许使用__cdecl调用约定绑定到函数。在我当前的项目中,向扩展/插件公开的所有功能都是使用__stdcall公开的。这使我无法直接绑定公开的对象,而是必须为公开的对象制作包装器。这很好,但是有很多对象需要包装。
例如,对象可以如下所示:
struct IObject
{
void __stdcall SomeFunc1( void );
void __stdcall SomeFunc2( const char* );
};
struct IObjectContainer
{
IObject* __stdcall GetObject( int );
IObject* __stdcall GetObject( const char* );
};
struct IObjectCore
{
IObjectContainer* __stdcall GetObjectContainer();
};目前,我没有办法更改调用约定的整个项目,所以我正在考虑是否有人有解决方案来修复Luabind以处理__stdcall函数。对于模板和boost功能,我不是最好的,所以我个人不知道从哪里开始添加使用__stdcall函数的能力。
作为参考,我正在使用:
Lua和Luabind都是他们版本的最新版本(由于项目限制的原因,不会使用Lua5.2,但是如果有一个用于5.2/Luabind的__stdcall修复,我也会很高兴地接受这一点)。
我只能为一个非常老版本的Luabind找到一个补丁来完成这个任务,但是仍然在网络上浮动的补丁与当前的Luabind代码完全不一致。
如果有任何其他需要的信息,请随意询问。
发布于 2012-11-22 18:39:50
可悲的是,由于缺乏活力,更多的搜索没有更多的答案,我与项目开发人员进行了交谈,并剥夺了整个项目的__stdcall。所以所有绑定现在都可以通过__cdecl很好地工作。不是我想走的路,但现在一切都按计划进行了。
发布于 2014-01-16 02:15:38
在将OpenGL (使用GLEW函数)绑定到Lua时,我遇到了完全相同的问题,并使用各种模板解决了这个问题。
现在,如果函数是全局的,并且在编译时知道它的地址,那么您可以很好地处理以下内容:
template<typename Signature>
struct wrap_known;
template<typename Ret, typename... Args>
struct wrap_known<Ret __stdcall (Args...)> {
template <Ret __stdcall functor(Args...)>
static Ret invoke(Args... arguments) {
return functor(arguments...);
}
};
// I know using macro is generally a bad idea but it's just shorter
#define wrap(f) wrap_known<decltype(f)>::invoke<f>然后,在绑定时,使用如下宏:
luabind::def("Clear", wrap(glClear)),
luabind::def("Vertex4f", wrap(glVertex4f))但是,在您的例子中,我们有一组成员函数,而不是像上面这样的全局函数。这里是用__stdcall调用约定包装成员函数的代码:
template<typename Signature>
struct wrap_mem;
template<typename Sub, typename Ret, typename... Args>
struct wrap_mem<Ret(__stdcall Sub::*) (Args...)> {
template <Ret(__stdcall Sub::*functor) (Args...)>
static Ret invoke(Sub* subject, Args... arguments) {
return (subject->*functor)(arguments...);
}
};
#define wrap_member(f) wrap_mem<decltype(f)>::invoke<f>像这样使用它:
struct A {
int __stdcall my_method(double b) {
return 2;
}
};
// ...
luabind::class_<A>("A")
.def("my_method", wrap_member(&A::my_method))但是,有时在编译时知道函数的地址并不是那么幸运,例如GLEW就是这样。对于像glUniform*f、glGetUniformLocation这样的函数,“work”宏将不能工作,所以我为包装运行时已知的函数做了另一个版本:
template<typename Signature>
struct wrap_unknown;
template<typename Ret, typename... Args>
struct wrap_unknown<Ret (__stdcall*) (Args...)> {
template <Ret (__stdcall** functor)(Args...)>
static Ret invoke(Args... arguments) {
return (**functor)(arguments...);
}
};
#define wrap_ptr(f) wrap_unknown<decltype(f)>::invoke<&f>(如果上面的代码吓到了你,那实际上是个好兆头)
现在您可以像这样绑定GLEW函数:
luabind::def("Uniform4f", wrap_ptr(glUniform4f)),
luabind::def("GetUniformLocation", wrap_ptr(glGetUniformLocation))只是不要要求我编写另一个版本,以便将指针绑定到运行时已知的成员:)
如果您出于某种原因不想使用C++11,here you can find out how to pass function arguments and return value as template parameters in C++03。
https://stackoverflow.com/questions/13288547
复制相似问题