在 Windows 到 Linux 项目转换中绕过 __declspec(dllimport)

Ben*_*rix 1 c++ linux dynamic-library

我正在将 Visual Studio C++ 框架转换为 Linux 版本,并且在消除 Windows 依赖项的过程中,我在一些头文件中遇到了一大堆 __declspec(dllimport) 调用。这些头文件定义了源文件中使用的一堆函数和类,因此构建需要它们。

下面是使用 __declspec() 调用的确切行。

#ifndef UeiDaqAPI
    #define UeiDaqAPI __declspec(dllimport)
#endif
Run Code Online (Sandbox Code Playgroud)

UeiDaqAPI 是所有源文件使用的类和函数的集合。据我了解, declspec 调用将当前 .h 文件中定义的函数/类链接到动态库“UeiDaqAPI”

Linux 不支持 __declspec(dllimport),因此我尝试使用 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
Run Code Online (Sandbox Code Playgroud)

然而,我收到错误消息,指出头文件中定义的函数调用未定义,我怀疑这是因为它们没有添加到 .so 库中,但我不确定。

我需要一些帮助来实现上述解决方法,或者,如果有更好的方法来绕过 __declspec() 调用,那么我需要一些关于从哪里开始的指针。

Fir*_*cer 5

您不需要使用dlopen,即用于动态加载(LoadLibrary/ dlopenGetProcAddress/ dlsymFreeLibrary/ dlclose)。

相反,与 Windows 的基本情况一样,它应该是自动的,但语法略有不同。

Windows/MSVC 通常只从 DLL 中导出由 DLL 明确告知的内容,__declspec(dllexport)然后在使用 DLL 时仅尝试链接由 明确告知的内容__declspec(dllimport)

然而,GCC/Linux 默认情况下(您可以选择显式导出样式)仅导出 中的所有内容.so,并且当链接考虑任何对象或库时,因此只需声明该函数就足够了,就像静态库或多个 C/ C++ 文件。

void my_uei_daq_api_function(int a, int b);
Run Code Online (Sandbox Code Playgroud)

通常在可移植库中可能会有以下内容:

#if defined(_WIN32) && defined(MYLIB_DLL)
#    ifdef MYLIB_BUILD
//       Compiling a Windows DLL
#        define MYLIB_EXPORT __declspec(dllexport)
#    else
//       Using a Windows DLL
#        define MYLIB_EXPORT __declspec(dllimport)
#    endif
// Windows or Linux static library, or Linux so
#else
#    define MYLIB_EXPORT
#endif
Run Code Online (Sandbox Code Playgroud)

然后在库标头中使用它:

MYLIB_EXPORT void my_uei_daq_api_function(int a, int b);
Run Code Online (Sandbox Code Playgroud)