以下の2つのコードセクションは、重要な情報を示しています。実際の作業は、3番目のコードセクションmain.cppで行われます。
// For all files:
typedef void (*func_ptr)(Event&); // Event is a class with certain methods
foo.cpp
extern "C" void init(std::map<std::string, func_ptr> *func_ptrs)
{
std::cout<<std::endl<<"Initializing..."<<std::endl; // does appear in output, so function does execute
(*func_ptrs)["test"] = stuff; // the stuff function below
}
// this is the function we are trying to add to the func_ptrs map
// It looks like it's added in main.cpp, but calling it in main.cpp seg faults
void stuff(Event &e)
{
std::cout<<"In stuff..."<<std::endl; // seg faults before this line
// do things with e
}
main.cpp
// Excluding fluff for brevity, use comments to understand location of problem
// In main....
map<string, func_ptr> func_ptrs; // map of strings to func_ptrs
void (*init)(map<string, func_ptr>*);
// some other stuff
handle = dlopen("libfoo.so", RLTD_NOW);
// library opens successfully
*(void **) (&init) = dlsym(handle, "init"); // get the init function from the library
// No, I don't completely understand the above sequence of pointers and reference, but it does open successfully
(*init)(&func_ptrs);
// Executes successfully
// Iterating over func_ptrs shows that the new "test" mapping is in func_ptrs!!
// Next, this should call the stuff function in foo.cpp that was assigned to func_ptrs["test"]
(func_ptrs["test"])(event); // seg fault
要約すると、
- libfoo.soライブラリが正しくロードされています
- libfoo.soのinitシンボルが正しく取得されています
- libfooのinit()が実行された後、マップキー「test」がmain.cppに表示されます
エラー:main.cppのマップfunc_ptrsにあるlibfooのものを実行しようとすると、セグメンテーション違反が発生します
注:別のオプションとして、main.cppに「マップに追加」関数を指定することもできます。これをlibfoo.soが呼び出すと、関数のリストにマッピングが追加されます。これは簡単/良いように見えますか?
私は多くの同様の質問/回答を見つけることができましたが、私が扱っている状況に十分に密接に関連する私の道を越えたものはありませんでした。皆さんの助けに感謝します、私はまだ失望していません。うまくいけば、私はコードを短くすることを台無しにしませんでした。