C++的lib不是跨编译器的

之前习惯了用win32的lib,或者别的在网上下载的sdk中的lib,不管msvc还是mingw-gcc,玩起来没多大差别。不过这次在wxWidget上栽了一上午……

作为话痨,我得说明背景。

大概两三个月之前,在玩音频相关的东西(本人三流吉他手啊),打算开启Audacity的VST插件功能看看效果;因为版权的问题,Audacity官网上的二进制没开启这个功能,所以需要下载源代码,改几个宏重新编译下。Audacity使用的wxWidget,于是下载了win平台的wxWidget开发包,按照Audacity的指示给wxWidget打上补丁,用vs2008编译之。编译成功后也顺利编译了Audacity,这是后话,不必说了。

在两三个月之后,突然想玩玩wxWidget,正好mingw32也更新了不少东西,就重新下了mingw32的一些包,用之前vs2008编译出来那些lib来玩,结果悲剧了一上午。链接器undefined reference的错误滚了好几屏,可那些lib哥已经指明了啊。一上午纠结在修改g++的编译命令行上(PS:这回用的rakefile,感觉不错),中饭后终于开始怀疑这些lib的问题。毕竟之前用的各种sdk基本都是纯C的,于是写了一个小例子。

 

 

#include <cstdio>
class FooClass {
  public:
    void go() {printf("go\n");}
};

int main(int argc, char** argv)
{
  FooClass obj;
  obj.go();
  return 0;
}

  然后分别用g++(gcc version 4.5.2)和msvc的cl.exe(vs2008附带版,15.00.30729.01)编译成obj,然后用objdump来查看编译出来的symbol table(毕竟lib就是几个obj的集合,所以obj的结果能说明lib的问题)。

 

首先是g++的版本:

 

SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 test.cpp
File 
[  2](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text$_ZN8FooClass2goEv
AUX scnlen 0x14 nreloc 2 nlnno 0 checksum 0x0 assoc 0 comdat 2
[  4](sec  5)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000000 __ZN8FooClass2goEv
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[  6](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _main
[  7](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x21 nreloc 2 nlnno 0
[  9](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[ 11](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[ 13](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rdata
AUX scnlen 0x3 nreloc 0 nlnno 0
[ 15](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 ___main
[ 16](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _puts

  其次是msvc的版本:

 

SYMBOL TABLE:
[  0](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00847809 @comp.id
[  1](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000001 @feat.00
[  2](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .drectve
AUX scnlen 0x45 nreloc 0 nlnno 0
[  4](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .debug$S
AUX scnlen 0x90 nreloc 0 nlnno 0
[  6](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x12 nreloc 1 nlnno 0 checksum 0x1c1b4d5d assoc 0 comdat 0
[  8](sec  3)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _main
[  9](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x18 nreloc 2 nlnno 0 checksum 0x13ab8126 assoc 0 comdat 2
[ 11](sec  4)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 ?go@FooClass@@QAEXXZ
[ 12](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _printf
[ 13](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rdata
AUX scnlen 0x4 nreloc 0 nlnno 0 checksum 0x1f95ab2d assoc 0 comdat 2
[ 15](sec  5)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 ??_C@_03MBCOILMO@go?6?$AA@

  很明显,FooClass中的go方法的函数名在symbol table中是不一样的,一个是__ZN8FooClass2goEv,一个是?go@FooClass@@QAEXXZ,难怪上午用g++去static链接msvc编译出的lib时会不停地找不到。

 

这个要是能统一该多好啊,我是有多么烦COM啊,如果C++的对象的二进制格式能定下来,各门语言也支持下,还真是不用用COM这种龌龊玩意儿了……

 

你可能感兴趣的:(C++,c,MinGW,binutils)