我来到这里是因为我遇到了一些奇怪的事情。
我有一个代码加载一个DLL并从这个DLL中检索一个函数。
我在windows和linux上工作
一切都像linux中的魅力一样,但是当Windows出现时,会出现一些问题!
我使用Clion作为IDE,当我编译我的代码并从Clion启动它时,一切正常,我的dll已加载,函数被取出,一切正常。
但是当我从它的目录启动我的应用程序时,我的应用程序找不到dll
这是我当前的加载程序代码(事实上这通常很简单):
void dllLoader(const char *libPath){
void* handle = dlopen(libPath, RTLD_LAZY | RTLD_GLOBAL);
if (!handle) {
std::cout << "Cannot open library: " << dlerror() << std::endl;
}
else{
std::cout << "library loaded" << std::endl;
dlclose(handle);
}
}
int main(int argc, char **argv) {
dllLoader("RenderModule.dll");
return 0;
}
正如我所说,从我的IDE运行这个很好(我得到“库加载”输出)但是当我在目录中运行并手动运行应用程序时,
我得到“无法打开库:RenderModule.dll没有这样的文件或目录”输出。
目标dll和二进制文件存储在同一目录中
我使用CMake 3.3和Mingw来编译这段代码
更奇怪的是,当我检查我的应用程序的运行路径,我尝试读取DLL,使用std :: ifstream,我可以正确读取DLL!可能我得不到的东西......
我不知道如何解决这个问题,有人有想法吗?
如果你需要dll代码,我将编辑这篇文章,但我不认为它是有用的,因为如果这个DLL被加载到linux / windows(在ide下)我认为问题不是来自dll,而是我错了。
提前谢谢你,对不起我的英文:/
祝你有愉快的一天!
答案 0 :(得分:0)
首先,感谢您的回复!对不起我的时间(我没有太多时间花在这个项目上)
我来到这里是因为我找到了解决我问题的方法,而且我认为这对于其他陷入困境的人来说可能会有所帮助#34; :P
我改变了我的&#34; dllLoader&#34;函数使用Win32 API:
void dllLoader(const char *libPath){
HMODULE handle = LoadLibrary(libPath);
if (!handle) {
std::cout << "Cannot open library: " << GetLastError() << std::endl;
}
else{
std::cout << "library loaded" << std::endl;
FreeLibrary(handle);
}
}
正如我所料,它落在第一个if分支和GetLastError返回错误代码127。 在一些搜索之后,在某些情况下检索到此错误代码,因为无法找到库依赖项。
在过去的时候,我尝试在IDE之外执行我用CLion编译的第一个应用程序
(手动,通过Windows资源管理器,这是一个简单的&#34;你好世界&#34;,所以没有理由失败)
我收到了一些错误,例如&#34; ...未解析的符号..&#34;,编译器在链接时没有链接所有需要的库,所以你的二进制文件
总是依赖于外部库。
我需要把
set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} "-static-libgcc -static-libstdc++ -static")
标记到我的CMake配置文件中以构建我的二进制文件,并在其中导入所有依赖项。
经过一些测试,问题在这里是一样的,我的DLL没有构建所有依赖项,它依赖和其他一些dll正确运行。 GCC_CXX_FLAGS的更新解决了加载dll而不是dll本身的应用程序的问题。 我不知道它是否存在类似的标志,使用cmake编译库,让链接器导入我的dll中的所有依赖项,但我知道我需要搜索什么。
@Alexey Omelchenko,你在评论中指出了一些有趣的东西,我在里面运行了一个应用程序,并且只显示了PATH env变量。 唯一的区别在于IDE里面的PATH为C:\ MingW \ bin文件夹,所以它确认了我的想法,这是一个依赖问题。
再次对不起我的英语和我的回复时间,感谢您的帮助:) 祝你有愉快的一天!