我的情况是我试图在共享对象构造函数中初始化文件范围变量 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;
}
我有一个非常简单的程序可以做同样的事情:如果你愿意的话,一个用于概念的测试驱动程序。其中的代码看起来像这样:一个“共享对象 ctor”,它在加载文件时使用 dladdr() 来存储 *.so 文件的路径。
我尝试过的修改:
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 中的更多对象]
在更大的项目中,我必须经历的障碍使得构建过程比我的小测试驱动程序所需的复杂得多。这让我觉得问题出在那儿。任何人都可以请阐明我所缺少的吗?
谢谢,安迪