C++ 当C++;11应用程序使用非C++;11图书馆
我有一个没有C++11标志(-std=C++11)编译的库和一个链接到该库的应用程序,该库是用-std=C++11构建的。它调用库中的函数,然后程序在库中崩溃得更深。我发现崩溃发生时函数的反汇编(它只是一个返回类中指针的简单函数)与调用堆栈从该程序生成时不同,而库的测试程序也不是用C++11标志构建的 操作系统是OSX Mountain Lion,编译器是Clang++ 为什么C++11应用程序和非C++11库之间不能使用,并且当不同生成的代码在库中时生成反汇编,因此应该是相同的 两种不同的分解:C++ 当C++;11应用程序使用非C++;11图书馆,c++,macos,c++11,shared-libraries,clang,C++,Macos,C++11,Shared Libraries,Clang,我有一个没有C++11标志(-std=C++11)编译的库和一个链接到该库的应用程序,该库是用-std=C++11构建的。它调用库中的函数,然后程序在库中崩溃得更深。我发现崩溃发生时函数的反汇编(它只是一个返回类中指针的简单函数)与调用堆栈从该程序生成时不同,而库的测试程序也不是用C++11标志构建的 操作系统是OSX Mountain Lion,编译器是Clang++ 为什么C++11应用程序和非C++11库之间不能使用,并且当不同生成的代码在库中时生成反汇编,因此应该是相同的 两种不同的分解
TestApplication`Core::GetPointer() const at System.h:xxx:
0x100009690: pushq %rbp
0x100009691: movq %rsp, %rbp
0x100009694: movq %rdi, -8(%rbp)
0x100009698: movq -8(%rbp), %rdi
0x10000969c: movq 64(%rdi), %rax ;<-------Difference
0x1000096a0: popq %rbp
0x1000096a1: ret
Lib1Prototype`Core::GetPointer() const at System.h:xxx:
0x100019c10: pushq %rbp
0x100019c11: movq %rsp, %rbp
0x100019c14: movq %rdi, -8(%rbp)
0x100019c18: movq -8(%rbp), %rdi
0x100019c1c: movq 40(%rdi), %rax ;<------Difference
0x100019c20: popq %rbp
0x100019c21: ret
TestApplication`Core::GetPointer()常量位于System.h:xxx:
0x100009690:pushq%rbp
0x100009691:movq%rsp,%rbp
0x100009694:movq%rdi,-8(%rbp)
0x100009698:movq-8(%rbp),%rdi
0x10000969c:movq 64(%rdi),%rax 在OS X使用的x86-64 ABI中,函数的第一个参数在%rdi
中传递,函数的返回值在%rax
中传递。因此,此函数采用指向某个数据结构的指针,并返回从偏移量64或40开始包含的64位值,具体取决于函数的编译方式
因此,您需要查看定义该数据结构的头文件。它根据您是否以C++11进行编译来定义不同的数据结构。也许有一些显而易见的东西,比如#ifdef
,你知道它的定义是不同的。或者可能有一个成员的类型定义不同。如果您无法理解,请编辑您的问题并粘贴(通过指针)传递到Core::GetPointer
函数的数据结构的定义。在OS X使用的x86-64 ABI中,函数的第一个参数在%rdi
中传递,函数的返回值在%rax
*中传递,因此该函数获取指向某个数据结构的指针,并返回从偏移量64或40开始包含的64位值,具体取决于函数的编译方式
因此,您需要查看定义该数据结构的头文件。它根据您是否以C++11进行编译来定义不同的数据结构。也许有一些显而易见的东西,比如#ifdef
,你知道它的定义是不同的。或者可能有一个成员的类型定义不同。如果您无法理解,请编辑您的问题并粘贴到(通过指针)传递到Core::GetPointer
函数的数据结构定义中。那么,库是否在其接口中公开了标准库的任何部分?它有一个C接口吗?它是一个相当大的库,有一个很大的接口,所以我没有检查每个函数签名,但它确实避免在其公共接口中公开标准库,但它肯定在内部使用它(头包含私有向量和映射)。它的接口是C++。那么,库是否在接口中公开了标准库的任何部分?它有一个C接口吗?它是一个相当大的库,有一个很大的接口,所以我没有检查每个函数签名,但它确实避免在其公共接口中公开标准库,但它肯定在内部使用它(头包含私有向量和映射)。它的接口是C++。在这个类声明中没有任何的IFIFF检查语言版本,但是有一个使用STD::vector的私有成员变量。标准的C++库链接在语言版本之间会有所不同,所以这可能是原因所在?当然是可能的。您可以检查
头文件以尝试找出它。。。或者只需记录类/结构的每个成员的sizeof
,以查看哪个成员具有不同的大小。结果是std::map(由核心继承的一个类使用)。它的大小有24字节的差异。@ AkAI:欢迎来到C++和二进制接口的世界。(提示:永远不要混搭。)在这个类的声明中没有#ifdef检查语言版本,但是有一个私有成员变量使用std::vector。标准的C++库链接在语言版本之间会有所不同,所以这可能是原因所在?当然是可能的。您可以检查
头文件以尝试找出它。。。或者只需记录类/结构的每个成员的sizeof
,以查看哪个成员具有不同的大小。结果是std::map(由核心继承的一个类使用)。它的大小有24字节的差异。@ AkAI:欢迎来到C++和二进制接口的世界。(提示:切勿混搭。)