我正在尝试构建一个Linux库(*.so)在Java应用程序中使用它。这个库本身会加载一个带有本地函数的dll文件。
这是我的c++代码:__delspec(dllexport) void __cdecl GetDllVersion(void){
typedef int(*GetDllVersion)(int*,int*,int*,int*);
void* lib = dlopen("~/lib.dll",RTLD_NOW);
cout << "Loading Symbol..." << endl;
GetDllVersion getVer= (GetDllVersion) dlsym(lib,"GetDllVersion");
dlclose(lib);
}
代码用wineg++ -shared lib.cpp -o libexports.so -Wl,--no-as-needed -ldl
编译,没有错误。
Java应用程序在循环中打印出"Loading Symbol…",然后在没有任何消息的情况下终止。我可以确定这与dlsym()有关。
有了nm -D lib.so
,我可以看到里面的库。函数GetDllVersion()确实是本库中的一个符号。
谁能告诉我为什么有一个无限循环和Java VM终止?
问候Wurmi
这一行:
void* lib = dlopen("~/lib.dll",RTLD_NOW);
将总是失败,因为dlopen
不做波浪扩展(一般来说,只有 shell做)。你真的应该检查dlopen
返回值
:
GetDllVersion getVer= (GetDllVersion) dlsym(lib,"GetDllVersion");
相当于dlsym(RTLD_DEFAULT, ...)
(因为RTLD_DEFAULT == 0
和lib == NULL
),因此返回一个指向您已经在其中的函数的指针,导致无限递归,并最终由于堆栈耗尽而崩溃。