[英]Loading classes from DLL that was exported by another compiler
如果我们计划从不同的编译器使用该DLL,我必须向我的团队解释为什么从DLL导出类不是一个好的解决方案。 但我找不到证明。 标准中是否存在诸如“编译器不应提供向后兼容性,不同的编译器也可以实现自己的命名导出符号的样式,因此从DLL导出的类可以被同一编译器使用”的东西? 我知道这是真的,但是我怎么证明呢? 另外,如果您知道我的其他说法,请帮忙!
您可能会发现以下几点有趣/有用,可以告诉您的团队。
不同的编译器对C ++名称的处理方式不同。 通过显示的.def文件可以解决此简单的名称处理问题。
需要正确的编译器选项(-mms-bitfields,...)的不同结构对齐问题。
基础异常和内存模型的根本冲突:
MSVC DLL中的new / delete或malloc / free不会与Cygwin newlib new / delete或malloc / free合作。 根本无法释放使用其他new / malloc在函数中分配的空间。
Cygwin可执行文件不会捕获MSVC DLL引发的异常,反之亦然。
慢速GNU SJLJ异常模型(在GCC-3.x和更早版本中使用)与MSVC ++模型兼容,但是新的DWARF2模型(将由GCC-4.x使用)将不兼容。
这里给出了更完整的解释,从这里我无耻地复制了上面的内容。 看到您使用MinGW时,这应该非常相关。
另外,如果您还没有这样做,请查看有关此SO问题的讨论。
不同的编译器使用不同的运行时库。 std::string
, std::vector<int>
, std::shared_ptr
都有不同的实现。 类具有不同的布局(对齐和打包仅是布局的一部分)。 如果甚至在任何地方甚至只有一个inline
函数,以及在需要分配内存的对象创建时,关于此布局的假设都会纳入两个模块。
C ++具有一个定义规则是有原因的,一旦您开始混合使用编译器,甚至使用不同的编译器选项,就会违反该规则。
这些是可以安全共享的东西:
请注意,这些都不要求dllexport
。 仅包含具有相同打包选项的相同头文件就足够了,因为通过v表而不是通过DLL导入可以找到函数。
当然,您还希望从DLL导出与C兼容的全局函数,以引导对象的创建。 对于那些__declspec(dllexport)
,或模块定义文件。 我也建议将extern "C"
用于这些全球出口。
我强烈建议您阅读“组件对象模型”(COM),它以其他各种名称命名,例如DCOM,ActiveX等。您不需要使用所有相同的机制,因为它们会非常复杂,但是尝试至少了解“仅具有虚拟功能的接口”和“具有自重新分配的引用计数”以及“对象本身继承了继承图”方案如何提供混合不同语言和编译器的能力。 (附带说明:COM的存在是仅v-table类兼容的原因,因为COM是Windows的v-table布局标准。它与Windows到ABI的距离非常近。)
嗯。我以为只有扩展的dll才能加载c ++类,而扩展的dll是针对MFC的,所以只有visual studio才能使我猜测。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.