reflection.cc
http://shinh.skr.jp/koneta/reflection_cpp.tar.gz
以下のように、 Test クラス内の test ではじまっているメソッドをイテレートして呼び出せます。
#include "reflection.h" #include <iostream> #include <cstring> using namespace std; class Test { void test_func1(); void test_func2(); void ignore(); }; void Test::test_func1() { cout << "func1" << endl; } void Test::test_func2() { cout << "func2" << endl; } void Test::ignore() { cout << "error" << endl; } int main() { Class* cl = Class::forName("Test"); if (!cl) { cout << "class Test not found" << endl; return 1; } typedef Class::Methods::const_iterator MethodIterator; for (MethodIterator ite = cl->methods.begin(); ite != cl->methods.end(); ++ite) { if (!strncmp(ite->first.c_str(), "test", 4)) { ((void (*) ())ite->second)(); } } return 0; }
Linux, FreeBSD, MacOSX, Solaris, Win32 で動いてます。
main でなんの初期化もせず Class::forName ではじまっているのは、 main 以前に .ctors セクションを利用して初期化をすませてあるから。
Win32API で気付いた点。 SymLoadModule で読めるシンボルは gcc 以外のコンパイラで作られたバイナリっぽい。 gcc で作ると読めない、だから今回は Win32 でも bfd を使ってます。
デマングラ書けば Win32 では GCC 以外でも動くと思う。
引数情報は取れるけど取っていない。返り値はシンボルの中に無いのでとりあえず取れない。