私が抱えている状況は、共有オブジェクトコンストラクターでファイルスコープ変数 std::string を初期化しようとしているということです。おそらくコードでより明確になるでしょう:
#include <string>
#include <dlfcn.h>
#include <cstring>
static std::string pathToDaemon; // daemon should always be in the same dir as my *.so
__attribute__((constructor))
static void SetPath()
{
int lastSlash(0):
Dl_info dl_info;
memset(&dl_info, 0, sizeof(dl_info));
if((dladdr((void*)SetPath, &dl_info)) == 0)
throw up;
pathToDaemon = dl_info.dli_fname; // **whoops, segfault here**
lastSlash = pathToDaemon.find_last_of('/');
if(std::string::npos == lastSlash)
{
// no slash, but in this dir
pathToDaemon = "progd";
}
else
{
pathToDaemon.erase(pathToDaemon.begin() + (lastSlash+1), pathToDaemon.end());
pathToDaemon.append("progd");
}
std::cout << "DEBUG: path to daemon is: " << pathToDaemon << std::endl;
}
これと同じことを行う非常に単純なプログラムがあります。コンセプトのテスト ドライバー プログラムです。その中のコードは次のようになります: ファイルがロードされたときに dladdr() を使用して *.so ファイルのパスを格納する「共有オブジェクト ctor」。
私が試した変更:
namespace {
std::string pathToDaemon;
__attribute__((constructor))
void SetPath() {
// function def
}
}
また
static std::string pathToDaemon;
__attribute__((constructor))
void SetPath() { // this function not static
// function def
}
と
std::string pathToDaemon; // variable not static
__attribute__((constructor))
void SetPath() { // this function not static
// function def
}
上記の例は、静的オブジェクト ライブラリと DLL の両方にコンパイルされたファイルにあります。コンパイルプロセス:
- static.a のオプション: --std=C++0x -c -Os。
- shared.so のオプション: -Wl,--whole-archive /path/to/static.a -Wl,--no-whole-archive -lz -lrt -ldl -Wl,-Bstatic -lboost_python -lboost_thread -lboost_regex - lboost_system -Wl,-Bdynamic -fPIC -shared -o mymodule.so [Python に静的なものをラップする多数のオブジェクト]
大規模なプロジェクトでジャンプしなければならないフープにより、小さなテスト ドライバー プログラムが必要とするよりもはるかに複雑なビルド プロセスが作成されます。これは、問題はそこにあると私に思わせます。誰かが私が欠けているものに光を当てることができますか?
ありがとう、アンディ