我有一个接口,我在一个共享库中实现了这个接口,谁知道它是用什么编译的。
dynamic_cast只对多态类型起作用。所以我可以假设它不使用RTTI,所以我确实禁用它,并且它编译。
由于没有标准化的多态处理方法,多态类型对象的布局是未知的,其vtable的布局也是未知的。
因此,问题就出现了:我是否可以使用与我使用的编译器不同的共享库中的多态类型对象?更重要的是,为什么?
发布于 2019-09-18 21:41:49
C++没有标准化的ABI,但是如果您的接口遵循一些规则,您可以实现大多数编译器之间的ABI兼容性--特别是在Windows上。这种技术在微软的COM (https://en.wikipedia.org/wiki/Component_Object_Model)中最著名,但我也在Steinberg的(https://steinbergmedia.github.io/vst3_doc/base/index.html)和"openvr“库(https://github.com/ValveSoftware/openvr/blob/5aa6c5f0f6520c59c4dce124541ecc62604fd7a5/headers/openvr.h#L1940)中看到过。
以下是与ABI兼容的C++接口的基本规则:
static_cast (以保证正确的this-pointer调整)。为了解决这个问题,每个COM接口都提供了QueryInterface()方法,这有点类似于一个QueryInterface()虚拟析构函数。一些编译器会生成多个vtable条目(请参阅Why do I have two destructor implementations in my assembly output?)。这意味着您必须实现自己的机制,以便从基指针中解构对象。COM和VST3与addRef()和release()一起使用引用计数,它们有自己的客户端智能指针类型。或者,您可以有一个简单的destroy()方法,并使用自定义的destroy()管理将对象实例存储在常规的std::unique_ptr或std::shared_ptr中,而不能跨越接口边界,也就是说,您不能在一边分配内存,而在另一端释放,因为每一方可能使用不同的运行时。库必须提供一个空闲函数或接口方法来释放对象。它还允许用户传递分配程序,因此内存管理停留在客户端。std::string,因为实现是不稳定的。来扩展它们。
class IFoo {
public:
virtual void foo() = 0;
};
class IFooEx : public IFoo {
public:
virtual void bar() = 0;
};或者添加一个新接口并使用多个继承。
尽管如此,作为一个库作者,在选择这种技术之前,您应该三思而后行,特别是当您计划为其他语言添加绑定时。虽然这种C++接口的vtable可以转换为函数指针的C结构,但通常的方法是
( a)从C API开始,并提供客户端C++包装器。
b)使用常规的C++接口,并在其之上提供C层。
但是,有了正确的抽象,类似COM的C++接口可以很好地进行编程。
https://stackoverflow.com/questions/57999911
复制相似问题