【问题标题】:MinGW fails to prefix _impl_ to exported functionsMinGW 无法为导出的函数添加前缀 _impl_
【发布时间】:2020-01-21 16:20:46
【问题描述】:

MinGW 应编译一个共享 C 库mylib,其中包含类似的函数

declspec(dllexport) int foo();

该库应在 Visual Studio 下的 C++ 应用程序中使用。

构建库(在 CMake 下,使用选项 GNUtoMS)生成三个文件,mylib.dll mylib.dll.a mylinb.lib。要检查后者,

dumpbin /HEADERS mylib.lib

为每个导出的函数打印一个姿态。上述函数foo 的立场包含这一行

Symbol name  : _foo

所以,MinGW生成前缀_imp_。预计链接依赖应用程序会失败,因为 Visual Studio 找不到 _imp_foo

如何做到这一点?

【问题讨论】:

  • 你写了“共享C库”,在Windows中就是“mylib.dll”。那你的“mylib.lib”是什么?它是如何产生的?
  • @jacob:我编辑了我的问题来回答你的评论。

标签: mingw cross-compiling dllexport


【解决方案1】:

这对我有用。我编译了这个源代码main.c

__declspec(dllexport) int foo()
{
    return 42;
}

用这个CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(mylib)

add_library(mylib SHARED "main.c")

使用这个脚本build.bat

set "PATH=C:\msys64\mingw64\bin;%PATH%"

cmake ^
    -G "MinGW Makefiles" ^
    -D CMAKE_GNUtoMS=ON ^
    -D CMAKE_GNUtoMS_VCVARS="C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvars64.bat" ^
    -D CMAKE_C_COMPILER="x86_64-w64-mingw32-gcc.exe" ^
    -D CMAKE_CXX_COMPILER="x86_64-w64-mingw32-g++.exe" ^
    .

cmake --build .

如您所见,我使用了 MSYS2 中的 MinGW-w64 而不是 MinGW,但这应该没有任何区别。输出是:

-- The C compiler identification is GNU 9.2.0
-- The CXX compiler identification is GNU 9.2.0
-- Check for working C compiler: C:/msys64/mingw64/bin/x86_64-w64-mingw32-gcc.exe
-- Check for working C compiler: C:/msys64/mingw64/bin/x86_64-w64-mingw32-gcc.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/x86_64-w64-mingw32-g++.exe
-- Check for working CXX compiler: C:/msys64/mingw64/bin/x86_64-w64-mingw32-g++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/jacob/Documents/prog/stackoverflow/GNUtoMS

C:\Users\jacob\Documents\prog\stackoverflow\GNUtoMS>cmake --build .
Scanning dependencies of target mylib
[ 50%] Building C object CMakeFiles/mylib.dir/main.c.obj
[100%] Linking C shared library libmylib.dll
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.4.3
** Copyright (c) 2019 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
Microsoft (R) Library Manager Version 14.24.28315.0
Copyright (C) Microsoft Corporation.  All rights reserved.

   Creating library libmylib.lib and object libmylib.exp
[100%] Built target mylib

然后我创建了一个程序prog.c

#include <stdio.h>

__declspec(dllimport) int foo();

int main (void)
{
    printf("%d\n", foo());
    return 0;
}

并使用编译它

cl.exe prog.c libmylib.lib -o prog.exe

链接成功,结果程序打印42。dumpbin.exe显示的符号是

  Symbol name  : foo

没有任何下划线和imps;尽管如此,它还是奏效了。

【讨论】:

  • 谢谢你,@jacob。下划线和 imps 并不意味着出现在源代码中;它们是自动生成的,至少在使用 VS 编译时是这样。您能否运行dumpbin libmylib.lib 并告诉我们您看到的是_foo 还是_imp_foo
  • @JoachimW 写在答案的最后。这就是最后一句话所指的。
  • 我试图重现您的最小示例,发现与我的环境的决定性区别是您使用x86_64-w64-mingw32-gcc 而不是mingw.exe。为了清楚档案记录,我将其作为单独的答案发布。为此,您的帮助至关重要。
【解决方案2】:

比起原来的 MinGW,更喜欢 fork MinGW-w64

代替

mingw.exe 来自http://MinGW.org

使用

x86_64-w64-mingw32-gcc 来自http://www.msys2.org

有了这个,dumpbin.exe 发现没有

Symbol name  : _foo

但是

Symbol name  : foo

Visual Studio 成功链接libmylib.lib

有关 mingw 与 msys2/mingw-w64 的背景信息,请参阅Wikipedia:“在 ... 2013 年启动了一个新项目,MSYS2 以及 32 位和 64 位 MinGW 包。创建此项目是为了保持跟踪 Cygwin 项目的最新进展……MSYS2 是对 MSYS 的独立重写,基于现代 Cygwin(POSIX 兼容层)和 MinGW-w64,旨在与原生 Windows 软件更好地互操作。”

MinGW is a registered trademark 授权给 MinGW projectMSYS2 project 中的编译器名称有些混乱:有时简称为 MinGW;即使专用于 64 位,可执行文件的名称中也包含 mingw32;官方名称好像是MinGW-w64

感谢@jacob,他在answer 中使用MinGW-w64 提供了决定性的提示。

【讨论】:

    猜你喜欢
    • 2021-03-15
    • 2019-09-29
    • 2019-01-22
    • 1970-01-01
    • 2012-04-03
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多