2

FFI を使用して C++ DLL をロードできないことはわかっています (C のみが機能します)。ラッパーを使用する必要がある場合、具体的にどのように開始すればよいですか?

編集: DLL を変更することはできません。

4

2 に答える 2

1

FFI の cdef で名前を手動でマングリングしてみることができますが、関数を参照するのが厄介なことは言うまでもなく、コンパイラによって異なる名前マングリング スキームが使用されます。

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*);
于 2014-05-30T01:55:18.437 に答える