вызов C ++ DLL из LuaJIT

Я знаю, что не могу использовать FFI для загрузки в C ++ DLL (будет работать только C), так как мне это сделать? Если мне нужно использовать оболочку, как именно с этого начать?

РЕДАКТИРОВАТЬ:
Я не могу изменить DLL никоим образом.

2

Решение

Вы можете попробовать изменить имена вручную в FDE cdefs, но разные компиляторы используют разные схемы распределения имен, не говоря уже о том, что ссылаться на функции было бы неудобно.

Вместо того, чтобы вручную манипулировать именами в cdef, я рекомендую написать некоторую оболочку на C. Хотя это утомительно, это не так уж сложно. Суть в том, что сторона C этого рассматривает классы как непрозрачные структуры для передачи функциям-оболочкам. Смотрите этот сайт для более подробной информации и некоторых ошибок, хотя.

Вот образец фрагмента обертки, который я использую для 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*);
1

Другие решения

Вы можете использовать C ++ DLL. Вам необходимо экспортировать такие функции (в MSVC):

extern "C" __declspec(dllexport)

Из-за искажения имени в C ++ (используется для перегрузки) ваша сигнатура функции не будет совпадать с именованием C. Например, эта функция:

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

Может быть экспортировано как что-то вроде foo@12abunchoflettershere используя именование C ++ вместо foo, как C именования будет.

Обратите внимание, что extern "C" не означает, что ваш код — чистый C. Вы можете использовать C ++ как обычно. Это все еще действует:

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

По вопросам рекламы [email protected]