c ++类实例内存布局再一次

j_k*_*bik 4 c++ memory layout shared-libraries

我知道之前已经问过这个问题,但在你给我一个减号并报告重复的问题之前,请考虑一下这个问题:

在之前的所有答案中,每个人都说对象内存布局依赖于编译器.那怎么样,共享库(*.dll,*.so)可以导出和导入c ++类,即使来自不同的编译器,它们肯定可以组合在一起?考虑一下在mingw下编写的DirectX应用程序.DirectX是使用MSVC++编译的,那么这些环境如何在内存布局上达成一致呢?我知道DirectX在很大程度上依赖于C++类和多态.

提出不同的要求:假设我有一个选择的架构(例如Windows,intel x86),我正在尝试编写一个新的编译器.我如何知道如何访问由另一个编译器编译的.dll lib提供的类实例(vtable,成员字段)?或者就是这样:M $编写了VC++,从那以后它就是不成文的标准,而且出于兼容性原因,其他所有编译器也都这样做了吗?那么linux或其他操作系统呢?

编辑:

好吧我承认,由于COM规范,DirectX的例子很糟糕......

另一个例子:QT.我正在使用QT和mingw,但我知道也有可用的MSVC版本.我不知道差异是仅在标题中,还是共享库(dll-s)也不同.如果它们是,那是否意味着我必须使用包含qt库的应用程序来分发我的应用程序,所以如果有人碰巧有一个用于不同编译器的应用程序,它将不会混淆?(好的记忆和代码共享,对吗?).或者他们是一样的,还有一些不成文的法律呢?

EDIT2:

我已经安装了一个不同的qt版本(msvc 2010),只是为了看看是什么和不共享.似乎共享(他们真的共享)库是不同的.似乎我真的必须在我的应用程序中提供qt-libs然后......这不是一件小事(例如QtGui 8-9MB).那些其他较小的库,其作者不是那么善于为其他编译器提供版本呢?这是否意味着我被他们的原始编译器困住了?如果我想使用由不同编译器编译的两个不同的库,该怎么办?

Jer*_*fin 8

基本上你问的是ABI.

在某些情况下(例如,在Itanium上),有一个指定ABI的文档,基本上每个人都遵循该文档.

在DirectX的情况下,它有点相同:微软已经发布了COM的规范,所以任何遵循这些规范的人都可以与任何COM对象互操作(原因之一 - 64位编译器可能无法工作使用为Windows 3.1编写的16位COM对象.

对于大多数其他事情,你或多或少都可以自己解决问题.在文档的方式中通常至少会发布一些内容,但至少根据我的经验,它经常会略过一些最终重要的细节,而不是完全可靠地更新,并且在某些情况下是完全错误的.在大多数情况下,它的组织也很差,因此您可以从任何可以找到它的地方收集到的信息,并且当您用尽信息(或耐心)时,请进行一些逆向工程以填补缺失的部分.

编辑:对于像Qt库这样的非COM事物,你有几个选择.一种是静态链接到Qt库,因此您需要的Qt代码直接链接到您的可执行文件.如果你想使用DLL,那么是的,你几乎坚持用你的应用程序分发一个,这将特定于你用来生成应用程序本身的编译器.不同的编译器(或者甚至是具有相同编译器的不同版本或编译标志集)通常需要不同的DLL(可能是相同的源代码,但是为了适应编译器的更改而构建).

这有例外,但它们就像我上面概述的那样.例如,用于Windows的英特尔编译器通常使用Microsoft的标准库,并且可以使用为Microsoft编译器构建的大多数(如果不是全部)其他库.这几乎是因为英特尔已经向后倾斜,以确保他们的编译器使用相同的调用约定,名称修改方案等,就像微软一样.它之所以有效,是因为他们付出了很多努力使其发挥作用,而不是因为任何不成文的法律,或类似的东西.