ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

c-在Windows上链接可执行文件的正确方法是什么?

2019-10-11 18:09:24  阅读:258  来源: 互联网

标签:c windows ld mingw mingw-w64


我需要在插件的主要可执行文件中使用一些符号.

链接可执行文件会导致以下链接器错误:

i686-w64-mingw32-g++ example.cpp -shared -I.. -std=c++11 -o test.dll ../../test.exe -static-libgcc -static-libstdc++ -fvisibility=hidden
[..]/test.exe:cygming-crtbegin.c:(.text+0x500): multiple definition of `__gcc_register_frame'
/usr/lib/gcc/i686-w64-mingw32/5.1.0/crtbegin.o:cygming-crtbegin.c:(.text+0x0): first defined here
[..]/test.exe:cygming-crtbegin.c:(.text+0x560): multiple definition of `__gcc_deregister_frame'
/usr/lib/gcc/i686-w64-mingw32/5.1.0/crtbegin.o:cygming-crtbegin.c:(.text+0x60): first defined here
[..]/test.exe: In function `ZlsRSoRK5Color':
[..]src/tools.h:212: multiple definition of `operator<<(std::ostream&, Color const&)'
/tmp/ccC97Hkz.o:example.cpp:(.text$_ZlsRSoRK5Color[__ZlsRSoRK5Color]+0x0): first defined here
../../test.exe: In function `ZN7MessageILb0EElsIcEERS0_OT_':
[..]/src/tools.h:241: multiple definition of `Message<false>& Message<false>::operator<< <char>(char&&)'
/tmp/ccC97Hkz.o:example.cpp:(.text$_ZN7MessageILb0EElsIcEERS0_OT_[__ZN7MessageILb0EElsIcEERS0_OT_]+0x0): first defined here
[..]/test.exe:crtexe.c:(.idata+0x3f0): multiple definition of `_imp__GeoIP_country_code'
[..]/test.exe:crtexe.c:(.idata+0x3f0): first defined here
[..]/test.exe:crtexe.c:(.idata+0x3f4): multiple definition of `_imp__GeoIP_country_name'
[..]/test.exe:crtexe.c:(.idata+0x3f4): first defined here
/usr/lib/gcc/i686-w64-mingw32/5.1.0/crtbegin.o:cygming-crtbegin.c:(.text+0x22): undefined reference to `_Jv_RegisterClasses'
collect2: error: ld returned 1 exit status

现在,如果我使用-shared -Wl构建主要可执行文件,则使用-export-all-symbols链接到test.exe即可,
但是Windows加载器(或至少是酒类加载器)抱怨test.exe是dll.

因此,我需要在没有-shared的情况下再次重新链接test.exe,以便能够运行test.exe.

即:

# produce the import executable
i686-w64-mingw32-g++ tools.o main.o [...] -o ../test.exe -shared -Wl,--export-all-symbols [...] -static-libgcc -static-libstdc++

# produce the real executable
i686-w64-mingw32-g++ tools.o main.o [...] -o ../test.exe -Wl,--export-all-symbols [...] -static-libgcc -static-libstdc++

那是超级骇客的,但最后我确实有一个有效的插件…

提出我的问题:

有没有更好的方法可以实现这一点(无需传递函数指针)?

我知道MSVC能够输出可执行文件的导入库,MinGW是否有类似的方法?

我尝试将-Wl,-out-implib,test.a添加到链接器标志中以获得可执行文件的导入库,
但是–out-implib似乎在链接可执行文件时被忽略.

解决方法:

在这种情况下,您可能确实想使用__declspec(dllexport)属性限定.exe中的回调符号.在我的Linux Mint Debian机器上交叉编译,以下最小示例对我有用:

$cat foo.c
#include <stdio.h>

int __declspec(dllexport) foo( int bar ){ return bar << 2; }
int main(){ printf( "%d\n", foo( 4 ) ); return 0; }

$mingw32-gcc -o ~/src/exp/foo.exe -Wl,--out-implib=libfoo.dll.a foo.c

这将生成一个工作的可执行文件,并生成一个导入库以映射其导出的符号,以供链接插件时使用,只需调用前面命令中的链接器即可(如在wine下运行可执行文件并列出文件名使用本地linux nm工具导入库):

$~/src/exp/foo.exe
16

$nm -A libfoo.dll.a
libfoo.dll.a:d000002.o:00000000 I _foo_exe_iname
libfoo.dll.a:d000002.o:00000000 i .idata$4
libfoo.dll.a:d000002.o:00000000 i .idata$5
libfoo.dll.a:d000002.o:00000000 i .idata$7
libfoo.dll.a:d000000.o:         U _foo_exe_iname
libfoo.dll.a:d000000.o:00000000 I __head_foo_exe
libfoo.dll.a:d000000.o:00000000 i .idata$2
libfoo.dll.a:d000000.o:00000000 i .idata$4
libfoo.dll.a:d000000.o:00000000 i .idata$5
libfoo.dll.a:d000001.o:00000001 a @feat.00
libfoo.dll.a:d000001.o:00000000 T _foo
libfoo.dll.a:d000001.o:         U __head_foo_exe
libfoo.dll.a:d000001.o:00000000 i .idata$4
libfoo.dll.a:d000001.o:00000000 i .idata$5
libfoo.dll.a:d000001.o:00000000 i .idata$6
libfoo.dll.a:d000001.o:00000000 i .idata$7
libfoo.dll.a:d000001.o:00000000 I __imp__foo
libfoo.dll.a:d000001.o:00000000 t .text

同样,可执行文件在WinXP中也可以正常运行(在LMDE框上的VirtualBox中运行,〜/ src / exp在WinXP VM中映射为驱动器E :,并从MSYS Shell中调用):

$/e/foo.exe
16

FWIW,当将-shared属性添加到链接器调用时,我可以重现您无法创建可运行的可执行文件的情况;如您所注意到的,它是用于创建DLL的(它们与可执行文件的格式不同,只是在标头中嵌入了不同的幻数;否则,它们基本上是相同的).

综上所述:

>链接可执行文件时,请不要指定-shared.
>使用|来限定要从可执行文件中导出的符号
__declspec(dllexport)属性.
>请在-Wl,-out-implib = lib< exename> .dll.a属性时指定
链接可执行文件.

标签:c,windows,ld,mingw,mingw-w64
来源: https://codeday.me/bug/20191011/1894308.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有