从LuaJIT调用C ++ DLL

时间:2014-05-29 15:59:37

标签: c++ c dll lua luajit

我知道我无法使用FFI加载C ++ DLL(只有C可以工作),所以我该怎样做呢?如果我需要使用包装器,我究竟该如何开始使用它?

编辑: 我无法以任何方式更改DLL。

2 个答案:

答案 0 :(得分:2)

您可以使用C ++ DLL。您需要导出这样的函数(在MSVC中):

extern "C" __declspec(dllexport)

由于C ++名称修改(用于重载),您的函数签名将与C命名不同。例如,这个函数:

int foo(char* a, int b, double c)

可以使用C ++命名导出类似foo@12abunchoflettershere的内容,而不是foo,就像C命名一样。

请注意,extern "C"并不意味着您的代码是纯粹的C.您可以正常使用C ++。这仍然有效:

extern "C" __declspec(dllexport) void foo(char *a, int b, std::shared_ptr<Foo> ptr)

答案 1 :(得分:1)

您可以尝试在FFI cdefs中手动修改名称,但不同的编译器使用不同的名称修改方案,更不用说引用这些函数会很尴尬。

我不建议在cdef中手动修改名称,而是建议在C中编写一些包装器。虽然单调乏味,但并不太难。它的要点是它的C端将类视为不透明的结构,以传递给包装函数。 See this site了解更多细节和一些陷阱。

这是我用于Box2D的包装器的示例代码段:

#include <Box2D/Box2D.h>

#ifdef __linux__
    #define CEXPORT extern "C"
#else
    #define CEXPORT extern "C" __declspec(dllexport)
#endif


// ///////////////////////////////////////////////////////
// World

CEXPORT b2World* b2World_new(b2Vec2* gravity) {
    return new b2World(*gravity);
}
CEXPORT void b2World_destroy(b2World* world) {
    delete world;
}
CEXPORT b2Body* b2World_createBody(b2World* world, const b2BodyDef* def) {
    return world->CreateBody(def);
}
CEXPORT void b2World_destroyBody(b2World* world, b2Body* body) {
    world->DestroyBody(body);
}
CEXPORT void b2World_step(b2World* world, float32 timeStep, int32 velIters, int32 posIters) {
    world->Step(timeStep, velIters, posIters);
}
CEXPORT b2Body* b2World_getBodyList(b2World* world) {
    return world->GetBodyList();
}

和相应的cdecl:

typedef struct b2World b2World;

b2World* b2World_new(b2Vec2*);
void     b2World_destroy(b2World*);
b2Body*  b2World_createBody(b2World*, const b2BodyDef*);
void     b2World_destroyBody(b2World*, b2Body* body);
void     b2World_step(b2World*, float, int32_t, int32_t);
b2Body*  b2World_getBodyList(b2World*);