尝试将使用visual c++编译的静态库链接到使用gcc编译的程序时未定义引用

jdgnovmf  于 2023-01-13  发布在  其他
关注(0)|答案(1)|浏览(164)

我尝试将使用Visual C++编译的静态库链接到使用GCC编译的程序,并调用someFunction()
在github上有库和程序的源代码
https://github.com/Kaspek2480/DoubleCompilersProblem

[1/2] Building CXX object CMakeFiles/myprogram.dir/main.cpp.obj
[2/2] Linking CXX executable myprogram.exe
FAILED: myprogram.exe 
cmd.exe /C "cd . && C:\dev-tools\mingw64\bin\c++.exe -O3 -DNDEBUG  CMakeFiles/myprogram.dir/main.cpp.obj -o myprogram.exe -Wl,--out-implib,libmyprogram.dll.a -Wl,--major-image-version,0,--minor-image-version,0  -LC:/Users/Kaspek/CLionProjects/LinkerTest/VisualCppStaticLibrary/cmake-build-release-visual-studio  -lmylibrary  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
c:/dev-tools/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/myprogram.dir/main.cpp.obj:main.cpp:(.text.startup+0xe): undefined reference to `someFunction()'```

垃圾箱:

Dump of file C:\Users\Kaspek\CLionProjects\LinkerTest\VisualCppStaticLibrary\cmake-build-release-visual-studio\mylibrary.lib

File Type: LIBRARY

   Linker Directives
   -----------------
   /DEFAULTLIB:MSVCRT
   /DEFAULTLIB:OLDNAMES
   /EXPORT:someFunction

  Summary

          60 .chks64
          DC .debug$S
          44 .drectve
          18 .pdata
          1C .rdata
          BA .text$mn
          20 .xdata

使用visual c++编译的库是用C写的,所以函数名不会被破坏。我的代码有什么问题?

mu0hgdu0

mu0hgdu01#

我可以使用gcc链接一个用微软cl命令行编译器编译的普通目标文件和一个用gcc编译的主文件,这两个文件都是C文件(提示cl将其视为C文件);我认为名称修饰方案阻止了来自不同源代码的C++派生对象文件的链接,除非将接口限制为C子集并声明那些函数extern "C"
在这两种情况下我都使用了各自的64位编译器。64位cl没有在函数名前面加上下划线(32位版本有)。gcc也没有。
当使用IDE进行编译时,传递给编译器的大约27个选项中的某些选项会导致cl调用生成对运行时库和调试库的调用;当从命令行用简单的/c调用时,它不会。当链接时,ld警告“def文件末尾的.drectve已损坏”;但是程序运行并产生一个退出值:

$ cat f.c
int f(int i) { return 4 + i;  }
$ cat main.c
int f(int i);
int main(){ return f(2); }

$ "/c/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe" /c f.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30141 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

f.c
$ nm f.obj
0000000000000000 N .chks64
0000000000000000 N .debug$S
0000000000000000 i .drectve
0000000000000000 t .text$mn
00000000010475bd a @comp.id
0000000080010190 a @feat.00
0000000000000002 a @vol.md
0000000000000000 T f
$ gcc -c main.c
$ nm main.o
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 p .pdata
0000000000000000 r .rdata$zzz
0000000000000000 t .text
0000000000000000 r .xdata
                 U __main
                 U f
0000000000000000 T main
$ gcc -o main main.o f.obj
Warning: corrupt .drectve at end of def file
$ ./main
$ echo $?
6

使用32位Microsoft编译器时,函数符号的名称为_f

$ "/c/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx86/x86/cl.exe" /c f.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30141 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

f.c
$ nm f.obj
00000000 N .chks64
00000000 N .debug$S
00000000 i .drectve
00000000 t .text$mn
010475bd a @comp.id
80010191 a @feat.00
00000002 a @vol.md
00000000 T _f

在这种情况下,main.cf()的声明必须更改为_f(),以便链接器可以找到该函数(我认为gcc工具链也需要是32位的)。

相关问题