在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() ()
答案 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 *头和方法时,这将是可能的。
总而言之,您的需求将在未来几个月得到支持,而不是在当下。对此我很抱歉,但我希望你理解。