联MinGW和MSVC之间困境(未定义参考)。 MinGW的失败MSVC工程(linking d

2019-08-19 11:40发布

我试图端口一个旧的C的.dll库最初MSVC完成使用BEA的Tuxedo库使用MinGW的。

我曾经遇到过的情况下MSVC编译和链接一个文件,但MinGW的失败。 实际问题是连接阶段。 总会有一个未定义的参考“错误。

这里的小例子,创建一个DLL:(tpsetunsol_test.c)

#include <atmi.h>

void __stdcall msghandler(char *pszMessage, long lMessageLen, long lFlags)
{

}   

int Inittpsetunsol()
{           
    int ret = 0;

    tpsetunsol(msghandler);

    return ret;                     
}   

这将编译没有错误:

gcc -Wall -fexceptions -g -O2 -DWIN32 -DNDEBUG -D_WINDOWS -ID:/dev/tuxedo/include   -o   tpsetunsol_test.o -c tpsetunsol_test.c

这里谈到的错误:

dllwrap --export-all-symbols -LD:/dev/tuxedo/lib -k --output-lib test.lib --output-def test.def --enable-stdcall-fixup --add-stdcall-alias -o IAWS.dll tpsetunsol_test.o -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lwtuxws32

C:\MinGW\bin\dllwrap.exe: no export definition file provided.
Creating one, but that may not be what you want
tpsetunsol_test.o: In function `Inittpsetunsol':
d:\dev\tpsetunsol_test.c:13: undefined reference to `tpsetunsol'
collect2.exe: error: ld returned 1 exit status
C:\MinGW\bin\dllwrap.exe: C:\MinGW\bin\gcc exited with status 1

函数声明中atmi.h:

extern void (_TMDLLENTRY * _TMDLLENTRY tpsetunsol _((void (_TMDLLENTRY *)(char _TM_FAR *, long, long)))) _((char _TM_FAR *, long, long));

#define _TMDLLENTRY __stdcall
#define _TM_FAR

版:

$ gcc -v
Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.7.2/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.7.2/configure --enable-    languages=c,c++,ada,fortran,objc,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgomp --disable-win32-registry --enable-libstdcxx-debug --disable-build-poststage1-with-cxx --enable-version-specific-runtime-libs     --build=ming
w32 --prefix=/mingw
Thread model: win32
gcc version 4.7.2 (GCC)

编辑:我发现了使用纳米由MSVC和GCC创建的对象文件符号tpsetunsol是不同

看着_tpsetunsol象征这是很明显的是MSVC和GCC产生不同的符号。

GCC生产: U _tpsetunsol和MSVC: U _tpsetunsol@4

编辑:纳米输出后,建立与Haroogan的建议:

$ dllwrap --export-all-symbols -LD:/dev/tuxedo.64/lib --output-lib test.lib --output-def test.def -o IAWS.dll tpsetunsol_test.o -lwtuxws32_new
C:\MinGW\bin\dllwrap.exe: no export definition file provided.
Creating one, but that may not be what you want
tpsetunsol_test.o: In function `Inittpsetunsol':
d:\dev\IA/tpsetunsol_test.c:13: undefined reference to `tpsetunsol'
collect2.exe: error: ld returned 1 exit status
C:\MinGW\bin\dllwrap.exe: C:\MinGW\bin\gcc exited with status 1


$ nm tpsetunsol_test.o
00000000 b .bss
00000000 d .data
00000000 N .debug_abbrev
00000000 N .debug_aranges
00000000 N .debug_info
00000000 N .debug_line
00000000 N .debug_loc
00000000 r .eh_frame
00000000 t .text
00000004 T _Inittpsetunsol
00000000 T _msghandler@12
         U _tpsetunsol

$ nm ../tuxedo.64/lib/libwtuxws32.a  | grep -i tpsetuns
00000000 I __imp__tpsetunsol@4
00000000 T _tpsetunsol@4

从预处理器的gcc(-E)(只有线tpsetunsol声明)输出

extern void (__attribute__((__stdcall__)) * __attribute__((__stdcall__)) tpsetunsol (void (__attribute__((__stdcall__)) *)(char *, long, long))) (char *, long, long);

Answer 1:

改变的声明tpsetunsol()atmi.h从标头:

extern void (_TMDLLENTRY * _TMDLLENTRY tpsetunsol _((void (_TMDLLENTRY *)(char _TM_FAR *, long, long)))) _((char _TM_FAR *, long, long));

至:

extern  void (_TMDLLENTRY * (_TMDLLENTRY tpsetunsol) _((void (_TMDLLENTRY *)(char _TM_FAR *, long, long)))) _((char _TM_FAR *, long, long));
//                          ^                      ^

这样的功能会得到妥善宣布为stdcall功能,因为它是在库(由指示@4库的后缀名)。



Answer 2:

正如你已经发现自己- 名称重整可以是跨不同的编译器。 为了解决您的问题,按照说明进行操作:

  1. 下载并安装(可以从源代码编译) gendef实用程序:

    • 如果你平时MinGW的 (针对32位),然后获得它这里 ;
    • 如果你的MinGW-W64 (针对64位),然后获得它在这里
  2. 运行gendef wtuxws32.dll (将生成wtuxws32.def );

  3. 运行dlltool -D wtuxws32.dll -d wtuxws32.def -l libwtuxws32.a (将生成libwtuxws32.a );

  4. libwtuxws32.aD:/dev/tuxedo/lib ;

  5. 现在,链接反对。



文章来源: linking dilemma (undefined reference) between MinGW and MSVC. MinGW fails MSVC works