【问题标题】:How do I properly export symbols into a windows DLL using MinGW?如何使用 MinGW 将符号正确导出到 Windows DLL 中?
【发布时间】:2017-08-01 18:32:47
【问题描述】:

我正在尝试使用 MinGW 创建一个具有一个公开函数的 C++ 库。

我想我已经阅读了足够的tutorials,浏览了互联网,但似乎没有任何效果,错误总是一样的。对函数的未定义引用。

这是库的头文件(findPoints.h):

#ifndef FIND_POINTS_H
#define FIND_POINTS_H

#ifdef BUILDING_FIND_POINTS_DLL
#define FIND_POINTS_DLL_PREFIX __declspec(dllexport)
#else
#define FIND_POINTS_DLL_PREFIX __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

FIND_POINTS_DLL_PREFIX void findPoints(uint8_t* data, int height, int width, int* cx, int* cy, int* lx, int* ly, int* rx, int* ry, int* quality);

#ifdef __cplusplus
}
#endif

#endif 

这是它的源文件(findPoints.h)中的函数声明:

#include "findPoints.h" 

//...

void FIND_POINTS_DLL_PREFIX findPoints(uint8_t* data, int height, int width, int* cx, int* cy, int* lx, int* ly, int* rx, int* ry, int* quality) {
    std::thread worker(findDroplet, data, height, width, cx, cy, lx, ly, rx, ry, quality);
    worker.detach();
}

该文件大约有 1000 行长(都是 findDroplet 声明的一部分,仅取决于标准库),所以我省略了,反正错误似乎不存在。

为了验证它是否正确,我将它包含在一个 main.cpp 文件中。虽然它在我使用时编译:

gcc main.cpp findPoints.cpp -o findPoints.exe

我无法创建一个可用的 dll(我需要一个 dll)。我就是这样做的:

g++ -c -O3 -DBUILDING_FIND_POINTS_DLL findPoints.cpp 
g++ -c main.cpp
g++ -shared -o findPoints.dll -Wl,--out-implib,libfindPoints.a
g++ -o findPoints.exe main.o -L. -lfindPoints

失败并显示错误消息:

main.o:main.cpp:(.text+0x1d5): undefined reference to `_imp__findPoints'

我尝试了各种前缀排列,但似乎没有任何效果。总是找不到 findPoins,根据前缀,它可以有一些前缀或后缀,但它永远不存在。我尝试了 dlltool,但它根本没有列出该函数。

看起来如果 cpp 文件中的 findPoints 函数被完全忽略,如果我更改它的名称,错误消息将保持不变。它们具有相同的签名,否则将它们一起编译将无法正常工作。

编辑:更多研究:我设法创建了一个 dll 库和一个使用 Visual Studio 使用它的 exe 程序。它可以工作(如果 dll 不存在,则会崩溃)。但是如果我尝试使用 MingGW 编译程序并将 dll 链接到它,错误仍然存​​在。现在问题已经解决了,但代价是需要大量的变通方法。不过,我还是想知道答案,因为我不喜欢 Visual Studio。

【问题讨论】:

    标签: c++ dll mingw


    【解决方案1】:

    当您创建 DLL 时,您不会将任何对象传递给 g++

    替换

    g++ -shared -o findPoints.dll -Wl,--out-implib,libfindPoints.a
    

    g++ -shared -o findPoints.dll findPoints.o -Wl,--out-implib,libfindPoints.a
    

    在您的构建序列中。

    【讨论】:

    • 感谢您的回复,但我现在尝试最终创建动态链接程序时,我得到No symbol version section for versioned symbol __cxa_finalize@@GLIBC_2.2.5'. Note that I had to add -fPIC` 来编译args。跨度>
    • 您是否正在尝试链接针对不同版本的 GNU C 库编译的附加库?
    • 这就是我的怀疑。我把它除了源代码全部删除了,重新编译它,错误仍然存​​在。自发布问题以来,我已经更改了一些内容,包括 glibc 的版本,但我不知道在删除除源代码之外的所有内容后它会有什么影响。我的 glibc s 2.24 版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多