本文介绍了升级到g ++ 4.7(支持c ++ 11):任何ABI不兼容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我的问题是,有任何ABI不兼容性 g ++编译器?是不是向后兼容?不是较新版本的编译器应该与现有的和传统的第三方静态库一起工作?



请注意,这只会发生在Windows(mingw)平台上。



有任何人使用Chilkat的MinGW C ++()静态)库在一个Windows应用程序的源代码是用g ++ 4.7.2编译的-std = c ++ 11编译选项?访问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 ++编译器编译---这是一个MINGW在ABI的具体更改吗?

 
#include< windows.h>
#include< stdio.h>
#include< CkString.h>
int main(int argc,char * argv []){
printf(test chilkat\\\
);
CkString str1;
printf(test done \\\
);
}



 
gdb -i = mi test_chilkat.exe
启动程序:test_chilkat .exe
[New Thread 4704.0x1a44]

程序接收到SIGSEGV信号,分段故障。
0x00404442在CkObject :: CkObject()()


解决方案

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



这里是我用的命令行将您的测试程序编译为汇编代码文件( ./ include 是Chilkat头文件的位置):

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

这里是两个 printf()调用注释的反汇编(GCC生成 puts

$




$ b

  call _puts 

lea eax,[esp + 28]; eax获取指向`str1`的指针
mov DWORD PTR [esp],eax;把str1指针放在栈上
call __ZN8CkStringC1Ev;调用`CkString :: CkString()`ctor

mov DWORD PTR [esp],OFFSET FLAT:LC1
call _puts


  • 4.7.2:

      call _puts 

    lea eax,[esp + 28]; eax获取指向`str1`的指针被构造
    mov ecx,eax; ecx获取`str1`这个指针
    LEHB0:
    call __ZN8CkStringC1Ev;调用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 。请参见



    您似乎可以覆写默认使用 -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的库更多...


    On Windows, when using g++ 4.6 (mingw) and -std=c++0x and linking with a third party static library (which was provided by the vendor for use with mingw), the application works fine. When I switched to g++ 4.7.2 (mingw) so that I could use -std=c++11, the application builds fine but crashes when run. If I comment out calls to the vendor provided library then it doesn't crash. I asked customer support of the library vendor and was told that this was not supported.

    My question is, "Are there any ABI incompatibilities" when going to a newer version of the g++ compiler? Is it not backward compatible? Aren't newer versions of the compiler supposed to work with existing and legacy 3rd party static libraries?

    Note that this only happens on Windows (mingw) platform. Works fine on Linux.

    I have added more info on this:

    Has anyone used Chilkat's MinGW C++ (static) libraries in a windows application whose source is compiled with g++ 4.7.2 with -std=c++11 compile option? The app crashes when Chilkat api is accessed (for e.g CkString object is instantiated). Works fine on g++ 4.6.2 (where I use std=c++0x).On Linux with g++ 4.7.2 this program works fine. If there is ABI incompatibility when moving from 4.6.2 to 4.7.2 then it shouldn't work on Linux also, right? Why would static library chilkat-9.3.2/lib/libchilkat.a created by vendor for use with MINGW care if the rest of the program is compiled with the latest g++ compiler --- is this a MINGW specific change in ABI?

    #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() ()
    
    解决方案

    MinGW 4.6.2 is definitely generating different code to call the CkString constructor than 4.7.2.

    Here's the command line I used to compile your test program to the assembly code file (where ./include is the location of the Chilkat headers):

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

    Here are annotated disassemblies bookended by the two printf() calls (which GCC generates as puts() calls).

    • 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
      

    As you can see, 4.6.2 passes the "this" pointer to the constructor on the stack (which is what the Chilkat library expects). 4.7.2 passes the "this" pointer in ecx.

    It looks like starting with 4.7.0. MinGW changed the C++ class-member calling convention to __thiscall. See http://mingw-users.1079350.n2.nabble.com/MinGW-GCC-4-7-0-released-td7578133.html

    It looks like you can override that default using the -mabi=sysv option, which makes your test program work for me:

    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
    

    However, you'll probably be buying yourself more trouble with other libraries in more complex programs - for example, you'll almost certainly need to rebuild libstdc++.a at the very least.

    I'd press the Chilkat developer for a 4.7.x library a bit more...

    这篇关于升级到g ++ 4.7(支持c ++ 11):任何ABI不兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-19 12:12