それできるよ!(環境限定で)
http://www.kmonos.net/wlog/88.html#_0843080805
> もし speak という特定のメソッド依存でない方法でこれが可能なSomeClassクラスの作り方をご存じなら、それは物凄いことだと思いますので、コードを公開していただけると冗談でなく泣いて喜びます。
#include <stdio.h> #include <dlfcn.h> extern "C" void test(void) { puts("TEST"); } class test_t { public: test_t() { puts("NEW"); } virtual ~test_t() { puts("DELETE"); } void bark(void) { puts("BARK"); } }; int main(void) { void* dlhandle; void (*fp)(void); void* (*test_new)(void); void (*test_delete)(void*); void (*test_bark)(void*); void* testp; test_t* tmp = new test_t(); tmp->bark(); delete tmp; dlhandle = dlopen(NULL, RTLD_LAZY); if (dlhandle == NULL) { puts("dlopen error"); return -1; } fp = (void(*)(void))dlsym(dlhandle, "test"); if (fp == NULL) { puts("dlsym test error"); return -1; } (*fp)(); test_new = (void*(*)(void))dlsym(dlhandle, "_ZN6test_tC1Ev"); if (test_new == NULL) { puts("dlsym new error"); return -1; } testp = (*test_new)(); test_bark = (void(*)(void*))dlsym(dlhandle, "_ZN6test_t4barkEv"); if (test_bark == NULL) { puts("dlsym bark error"); return -1; } (*test_bark)(testp); test_delete = (void(*)(void*))dlsym(dlhandle, "_ZN6test_tD1Ev"); if (test_delete == NULL) { puts("dlsym delete error"); return -1; } (*test_delete)(testp); return dlclose(dlhandle); }
$ g++ -O0 -g -fPIC -ldl -Wl,-export-dynamic main.cc
$ a.out
NEW
BARK
DELETE
TEST
NEW
BARK
DELETE
という感じですね。手元のLinuxでしか試していませんが、POSIX系でdlがある環境なら動くはずです。
要注意ポイントとして
- 動的にクラス名を取ってくる部分を書いていない。
- 関数名はobjdump -Dを読んで決めた。
- 呼び出し規約を騙している。(cdecl->stdcall)
- class test_tが最適化で消えるかも。
というのがあるので実用には足りませんが。