C++のlibはコンパイラ間ではありません


以前はwin 32のlib、あるいは他のネット上でダウンロードしたsdkのlibに慣れていましたが、msvcでもmingw-gccでも、あまり違いはありませんでした.でも今回はwxWidgetに午前中植えました・・・
話として、背景を説明しなければなりません.
2、3ヶ月くらい前に、オーディオ関連のもの(本人三流ギタリストかな)をプレイして、AudacityのVSTプラグイン機能をオンにして効果を見ようとしました.著作権の問題で、Audacityの公式サイトのバイナリはこの機能を開いていないので、ソースコードをダウンロードし、いくつかのマクロを変更して再コンパイルする必要があります.Audacityが使用するwxWidgetは、winプラットフォームのwxWidget開発パッケージをダウンロードし、Audacityの指示に従ってwxWidgetにパッチを適用し、vs 2008でコンパイルした.コンパイルに成功してAudacityも無事にコンパイルできましたが、これは後の話で、言うまでもありません.
2、3ヶ月後、突然wxWidgetを遊びたいと思って、ちょうどmingw 32も多くのものを更新して、mingw 32のいくつかのバッグを再ダウンロードして、前のvs 2008でそれらのlibをコンパイルして遊びに来て、結局悲劇は午前中でした.リンクundefined referenceのエラーは何画面も転がっていましたが、lib兄はすでに指定していますね.午前中、g++のコンパイルコマンドラインを修正することに葛藤し(PS:今回使ったrakefile、いい感じ)、昼食後、ついにこれらのlibの問題を疑い始めた.なにしろこれまで使っていた様々なsdkは基本的に純粋なCなので、小さな例を書きました.
 
 
#include <cstdio>
class FooClass {
  public:
    void go() {printf("go
");} }; int main(int argc, char** argv) { FooClass obj; obj.go(); return 0; }

その後、g++(gcc version 4.5.2)とmsvcのcl.exe(vs 2008付属版、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で異なり、1つは__である.ZN 8 FooClass 2 goEv、一つは?go@FooClass@@QaEXXZ、道理で午前中にg++でstaticリンクmsvcでコンパイルしたlibに行くと見つからない.
 
これが统一できたらどんなにいいか、私はどんなにCOMに迷惑をかけているのか、もしC++の対象のバイナリフォーマットが决まったら、各言语も支持して、本当にCOMのような汚いものを使う必要はありません......