【发布时间】:2020-04-30 06:30:58
【问题描述】:
我正在将 Visual Studio C++ 框架转换为 linux 版本,并且在消除 Windows 依赖项的过程中,我在一些头文件中遇到了一大堆 __declspec(dllimport) 调用。这些头文件定义了一堆在源文件中使用的函数和类,因此构建时需要它们。
以下是使用 __declspec() 调用的确切行。
#ifndef UeiDaqAPI
#define UeiDaqAPI __declspec(dllimport)
#endif
UeiDaqAPI 是所有源文件使用的类和函数的集合。据我了解,declspec 调用将当前 .h 文件中定义的函数/类链接到动态库“UeiDaqAPI”
__declspec(dllimport) 不受 linux 支持,因此我尝试了使用 dlopen() 的“解决方法”。有关更多背景信息,大约 40 个头文件使用上述 __declspec() 调用,因此测试任何解决方法都非常乏味。我得到了一个用于 linux 的动态库,采用我应该使用的 .so 格式。
我找到了一个使用 dlopen(path-to-library) 的示例,它应该可以让我绕过 __declspec() 调用,但我不确定如何让它正常工作。到目前为止,我已经尝试按照示例进行操作,并更改了所有 40 个左右的头文件,并将 __declspec() 调用替换为以下内容:
#ifndef UeiDaqAPI
string nameOfLibToLoad("path/to/lib/lib.so");
UeiDaqAPI = dlopen(nameOfLibToLoad.c_str(), RTLD_LAZY);
if (!lib_handle) {
cerr << "Cannot load library: " << dlerror() << endl;
}
#endif
但是,我收到错误消息,指出未定义在头文件中定义的函数调用,我怀疑这是因为它们没有被添加到 .so 库中,但我不确定。
我想要一些帮助来实现上述解决方法,或者,如果有更好的方法来绕过 __declspec() 调用,那么 id 想要一些关于从哪里开始的指针。
【问题讨论】:
-
dllimport和dllexport是 Windows 特定的 DLL 概念。 Linux 本身不使用.dll二进制文件; Linux 使用shared object (.so) 二进制文件。您是否尝试在您的 Linux 应用程序中专门加载.dll文件? -
我对基于 linux 的库加载不太熟悉,但是是的,dllimport 尝试加载一个 dll,我显然没有,所以我正在寻找一种方法来绕过这个 dllimport 调用。我已经有一个应该使用的 .so 二进制文件,但我不确定如何告诉 .h 文件使用 .so 而不是使用 dllimport 加载 dll
-
@Romen 我如何专门链接到
.so文件。这就是我苦苦挣扎的地方,如何将每个头文件准确链接到.so -
链接
.so文件的方式与链接.lib或.a库的方式相同。我认为您可能需要寻找一本 C++ 书籍或教程,以确保您对链接器、库和头文件如何协同工作有一个很好的理解。在 linux 上您需要做的就是包含库的标头,并链接到该库的.so。无需像使用 Windows DLL 那样显式导入或导出函数;在 linux 上,.so可以像静态库一样使用。 -
还有@Bendrix,我认为指出您在代码中看到的
dllimport不调用函数或执行任何操作 可能会有所帮助。它是一个属性,是一个函数的描述,它告诉编译器/链接器该函数存在于一个DLL 中。加载 DLL 的实际代码是编译器自动插入的,只要您链接到该 DLL 的.lib文件。
标签: c++ linux dynamic-library