升级到g ++ 4.7(支持c ++ 11):任何ABI不兼容?

时间:2012-10-27 12:49:20

标签: c++ windows mingw chilkat

在Windows上,当使用g ++ 4.6(mingw)和-std = c ++ 0x并链接第三方静态库(由供应商提供用于mingw)时,应用程序正常工作。当我切换到g ++ 4.7.2(mingw)以便我可以使用-std = c ++ 11时,应用程序构建正常但运行时崩溃。如果我注释掉对供应商提供的库的调用,那么它不会崩溃。我询问了图书馆供应商的客户支持,并被告知这不受支持。

我的问题是,“在使用更新版本的g ++编译器时,”是否存在任何ABI不兼容性“?它不向后兼容吗?是不是新版本的编译器可以与现有的和第三方的静态库一起使用?

请注意,这只发生在Windows(mingw)平台上。适用于Linux。

我在此添加了更多信息:

有没有人在一个Windows应用程序中使用Chilkat的MinGW C ++(静态)库,其源代码是使用带有-std = c ++ 11编译选项的g ++ 4.7.2编译的?访问Chilkat api时应用程序崩溃(例如,实例化CkString对象)。在g ++ 4.6.2上工作正常(我使用std = c ++ 0x)。 在Linux上使用g ++ 4.7.2,这个程序运行正常。如果从4.6.2移动到4.7.2时存在ABI不兼容,那么它也不适用于Linux,对吧?为什么静态库chilkat-9.3.2 / lib / libchilkat.a由供应商创建用于MINGW,如果程序的其余部分是用最新的g ++编译器编译的话 - 这是ABI中MINGW特定的变化吗?

#include <windows.h>
#include <stdio.h>
#include <CkString.h>
int main(int argc, char *argv[]) {
  printf("test chilkat\n");
  CkString str1;
  printf("test done\n");
}
gdb -i=mi test_chilkat.exe
Starting program: test_chilkat.exe
[New Thread 4704.0x1a44]

Program received signal SIGSEGV, Segmentation fault.
0x00404442 in CkObject::CkObject() ()

2 个答案:

答案 0 :(得分:4)

MinGW 4.6.2肯定会产生不同的代码来调用CkString构造函数而不是4.7.2。

这是我用来将测试程序编译到汇编代码文件的命令行(其中./include是Chilkat标题的位置):

g++ -I ./include -S -masm=intel -std=gnu++0x test.cpp

以下是由两个printf()调用(GCC生成puts()调用)预订的带注释的反汇编。

  • 4.6.2:

    call    _puts
    
    lea eax, [esp+28]           ; eax gets pointer to `str1` being constructed
    mov DWORD PTR [esp], eax    ; put the `str1` pointer on the stack
    call    __ZN8CkStringC1Ev   ; call `CkString::CkString()` ctor
    
    mov DWORD PTR [esp], OFFSET FLAT:LC1
    call    _puts
    
  • 4.7.2:

    call    _puts
    
    lea eax, [esp+28]           ; eax gets pointer to `str1` being constructed
    mov ecx, eax                ; ecx gets `str1` "this" pointer
    LEHB0:
    call    __ZN8CkStringC1Ev   ; call `CkString::CkString()` ctor
    
    mov DWORD PTR [esp], OFFSET FLAT:LC1
    call    _puts
    

如您所见,4.6.2将“this”指针传递给堆栈上的构造函数(这是Chilkat库所期望的)。 4.7.2在ecx中传递“this”指针。

看起来像从4.7.0开始。 MinGW将C ++类成员调用约定更改为__thiscall。见http://mingw-users.1079350.n2.nabble.com/MinGW-GCC-4-7-0-released-td7578133.html

看起来您可以使用-mabi=sysv选项覆盖该默认值,这使您的测试程序适合我:

C:\temp>g++ --version
g++ (GCC) 4.7.2
...

C:\temp>g++ -mabi=sysv -I ./include -g -Wl,--enable-auto-import test.cpp -o test.exe libchilkat-9.3.2.a

C:\temp>test
test chilkat
test done

但是,你可能会在更复杂的程序中使用其他库给自己带来更多麻烦 - 例如,你几乎肯定需要至少重建libstdc++.a

我会再次向Chilkat开发人员推送4.7.x库...

答案 1 :(得分:3)

我是供应商(Chilkat),对Babu的回答并不是“不支持”,而是“尚未支持”。

在每个Chilkat版本之间,不可避免地需要支持的新系统。每个都需要时间(在Chilkat)生产用于建造和分配的自动化系统。处于新事物的最前沿,并期望它立即得到Chilkat的支持有点不合理。

目前,Chilkat计划支持以下新系统:Windows Phone 8,Embarcadero XE3,Mono(适用于Windows的跨平台,Linux,MAC OS X,iOS,Android等),任何新版本Perl,Python,PHP等,如Python 3.3.0,Android for MIPS和x86。 Chilkat还以其他方式提供API,这些方式不一定是“新的”,例如以类似于“C”API的方式提供DLL / .so / .dylib功能库。

作为跨平台API合理性的一部分,正在进行重大的内部开发。例如,将完全生成“Ck *”C ++标头和实现。 .NET程序集托管标头和实现也是如此,每个标头和实现都调用相同的内部实现。这将做两件事(1)消除平台之间的任何不一致,以及(2)允许进行外层的改进/改变。例如,如果需要为每个C ++类方法添加一个调用约定修饰符。也许添加“_ stdcall”或“ _chilkat_call”,其中“__chilkat_call”可以在一个地方定义为什么都没有,“_ stdcall”或“ _thiscall”会有所帮助。当生成Ck *头和方法时,这将是可能的。

总而言之,您的需求将在未来几个月得到支持,而不是在当下。对此我很抱歉,但我希望你理解。