联MinGW和MSVC之间的两难选择(未定义参考)。 MinGW的失败作品MSVC [英] linking dilemma (undefined reference) between MinGW and MSVC. MinGW fails MSVC works

查看:2792
本文介绍了联MinGW和MSVC之间的两难选择(未定义参考)。 MinGW的失败作品MSVC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

 的#include< atmi.h>无效__stdcall msghandler(字符* pszMessage,长lMessageLen,长LFLAGS)
{}INT Inittpsetunsol()
{
    INT RET = 0;    tpsetunsol(msghandler);    返回RET;
}

这编译没有错误:

 的gcc -Wall -g -fexceptions -O2 -DWIN32 -DNDEBUG -D_WINDOWS -ID是:/ dev /晚礼服/ -o包括-c tpsetunsol_test.o tpsetunsol_test.c

这里谈到的错误:

  dllwrap --export-全符号-LD是:/ dev /晚礼服/ lib目录-k --output-LIB test.lib --output高清test.def --enable -stdcall-修正--add-STDCALL别名-o IAWS.dll tpsetunsol_test.o -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lwtuxws32C:\\ MinGW的\\ BIN \\ dllwrap.exe:没有提供导出定义文件。
创建的,但是这可能不是你想要什么
tpsetunsol_test.o:在功能`Inittpsetunsol:
D:\\ dev的\\ tpsetunsol_test.c:13:未定义的参考`tpsetunsol
collect2.exe:错误:LD返回1退出状态
C:\\ MinGW的\\ BIN \\ dllwrap.exe:C:\\ MinGW的\\ BIN \\ GCC退出,状态1

在atmi.h函数声明:

 的extern无效(_TMDLLENTRY * _TMDLLENTRY tpsetunsol _((无效(_TMDLLENTRY *)(CHAR _TM_FAR *,很久))))_((CHAR _TM_FAR *,很久) );#定义_TMDLLENTRY __stdcall
#定义_TM_FAR

版本:

  $ gcc的-v
使用内置的规格。
COLLECT_GCC = C:\\ MinGW的\\ BIN \\ gcc.exe
COLLECT_LTO_WRAPPER = C:/ MinGW的/ bin中/../的libexec / GCC / mingw32的/ 4.7.2 / LTO-wrapper.exe
目标:mingw32的
配置有:../gcc-4.7.2/configure --enable-语言= C,C ++,ADA,FORTRAN,objc,OBJ-C ++ --disable-sjlj的异常--with-DWARF2 --enable-共享 - -enable-libgomp --disable-Win32的注册表--enable-libstdcxx调试--disable-集结poststage1与 - CXX --enable-版本特有的运行时库--build =明
W32 - preFIX = / MinGW的
线程模型:的Win32
gcc版本4.7.2(GCC)

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

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

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

编辑:纳米输出构建Haroogan的建议后:

  $ dllwrap --export-全符号-LD:/dev/tuxedo.64/lib --output-LIB test.lib --output高清test.def -o IAWS.dll tpsetunsol_test.o -lwtuxws32_new
C:\\ MinGW的\\ BIN \\ dllwrap.exe:没有提供导出定义文件。
创建的,但是这可能不是你想要什么
tpsetunsol_test.o:在功能`Inittpsetunsol:
D:\\ dev的\\ IA / tpsetunsol_test.c:13:未定义的参考`tpsetunsol
collect2.exe:错误:LD返回1退出状态
C:\\ MinGW的\\ BIN \\ dllwrap.exe:C:\\ MinGW的\\ BIN \\ GCC退出,状态1
$纳米tpsetunsol_test.o
00000000 b的.bss
00000000Ð。数据
00000000ñ.debug_abbrev
00000000ñ.debug_aranges
00000000ñ.debug_info
00000000ñ.debug_line
00000000ñ.debug_loc
00000000 - [R .eh_frame
0000万吨的.text
00000004ŧ_Inittpsetunsol
00000000ŧ_msghandler @ 12
         ü_tpsetunsol$纳米../tuxedo.64/lib/libwtuxws32.a | grep的-i tpsetuns
00000000我__imp__tpsetunsol @ 4
00000000ŧ_tpsetunsol @ 4

从GCC preprocessor(-E)(仅限该行tpsetunsol声明)输出

 的extern无效(__attribute __((__ stdcall__))* __attribute __((__ stdcall__))tpsetunsol(无效(__attribute __((__ stdcall__))*)(字符*,很久))) (字符*,很久);


解决方案

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

 的extern无效(_TMDLLENTRY * _TMDLLENTRY tpsetunsol _((无效(_TMDLLENTRY *)(CHAR _TM_FAR *,很久))))_((CHAR _TM_FAR *,很久) );

 的extern无效(_TMDLLENTRY *(_TMDLLENTRY tpsetunsol)_((无效(_TMDLLENTRY *)(CHAR _TM_FAR *,很久))))_((CHAR _TM_FAR *,长,长));
// ^^

这样的功能将被正确声明为 STDCALL 的功能,因为它是在库(由 @ 4 库中的名称后缀)。

I'm trying to port an old C .dll library originally done with MSVC that uses BEA Tuxedo library to use MinGW.

I have encountered a situation where MSVC compiles and links one file but MinGW fails. The actual problem is in linking stage. There comes 'undefined reference' error.

Here's the minimal example to create a 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;                     
}   

This compiles without errors:

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

Here comes the error:

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

function declaration in 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

Version:

$ 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)

Edit: I found out using nm on object files created by MSVC and GCC that symbol tpsetunsol is different

Looking at _tpsetunsol symbol it is quite evident that MSVC and GCC produce different symbols.

GCC produces: U _tpsetunsol and MSVC: U _tpsetunsol@4

Edit: nm output after build with Haroogan's suggestion:

$ 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

output from gcc preprocessor (-E) (only the line tpsetunsol is declared)

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

解决方案

Change the declaration of tpsetunsol() in the atmi.h header from:

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

to:

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

so the function will be properly declared to be a stdcall function as it is in the library (as indicated by the @4 suffix on the name in the library).

这篇关于联MinGW和MSVC之间的两难选择(未定义参考)。 MinGW的失败作品MSVC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆