C++ GCC:如何在不导出整个类的情况下导出(所选方法和)类的vtable/typeinfo?
我在共享库中拥有此类:C++ GCC:如何在不导出整个类的情况下导出(所选方法和)类的vtable/typeinfo?,c++,gcc,dllexport,C++,Gcc,Dllexport,我在共享库中拥有此类: class Interface { int m_ref; public: FOO_EXPORT virtual ~Interface(); virtual void foo() = 0; protected: void ref() { ++m_ref; } bool deref() { return --m_ref; } }; // cpp file: Interface::~Interface() {} 其中,FOO\u E
class Interface {
int m_ref;
public:
FOO_EXPORT virtual ~Interface();
virtual void foo() = 0;
protected:
void ref() { ++m_ref; }
bool deref() { return --m_ref; }
};
// cpp file:
Interface::~Interface() {}
其中,FOO\u EXPORT
是GCC的\uu属性((可见性=默认值))
,我使用-fvisibiliy=hidden-fvisibility inlines hidden
进行编译
但是当我使用另一个库中的接口时,我会得到typeinfo和vtable的未定义引用
在MSVC上,其中FOO_EXPORT
是declspec(dllexport/dllimport
)`,这可以正常工作,因为vtable是在导出虚拟函数时导出的
我当然可以导出整个类:
类FOO_导出接口{
但这也会导出所有内联方法
是否有一个中间地带可以导出~Interface()
和vtable,而不导出其他内容
如果您知道:为什么GCC与MSVC不兼容?为什么GCC与MSVC不兼容?
因为GCC/G++和MSVC是不同的东西?MSVC++还有u declspec(novtable)属性,应该在接口上使用,因为它们的vtable永远不应该被使用。只使用实现该接口的具体类的vtable。我们看不到您在客户端代码中犯了这样的错误,我想您应该将构造函数设为私有,以便获得更好的错误消息。@HansPassant:Re:“vtable[接口的]“永远不应该被使用”:我不同意:假设你有两个像上面OP中那样的接口:class InterfaceA;class InterfaceB;
。那么dynamic_cast
的有效用例是:void foo(InterfaceB*ifaceB){if(IfaceA*IfaceA=dynamic_cast(ifaceB)){/*对象也实现了InterfaceA*/}
。这正是我需要导出vtable/typeinfo的原因:如果不导出vtable/typeinfo,则强制转换可能会失败,请参阅“异常问题”(动态强制转换的相同问题)。这是RTTI,不是vtable。您正在使用第三个函数QueryInterface:)有一个名为-fvisibility ms compat
的选项,可以缓解此问题。但是,到目前为止,它还没有: