草庐IT

c++ - 升级到 g++ 4.7(支持 c++11): any ABI incompatibility?

coder 2024-06-07 原文

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

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

请注意,这仅发生在 Windows (mingw) 平台上。在 Linux 上运行良好。

我已经添加了更多信息:

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

最佳答案

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

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

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 库...

关于c++ - 升级到 g++ 4.7(支持 c++11): any ABI incompatibility?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13100324/

有关c++ - 升级到 g++ 4.7(支持 c++11): any ABI incompatibility?的更多相关文章

  1. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  4. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  5. ruby - 在不使用 RVM 的情况下在 Mac 上卸载和升级 Ruby - 2

    我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐