C ++ DLL类导出,编译器“优化”虚拟调用

时间:2020-06-29 06:11:19

标签: c++ c dll dllimport

我正在创建DLL API(MSVC12),我真的想使用类导出。

问题是:我有一个嵌套类,其调用被视为“直接调用”,
我没有找到强制执行虚拟表调用的优雅方法。

(注意:为了便于阅读,我修剪了一些界面)

// interface.h
class CEvent {
public:
 virtual bool hasOccured();
}
class ISimulator {
public:
 virtual void Init();
 CEvent initEnded;
}

void DLL_API_INTERFACE ISimulator* GetSimulator();

// interface.c - DLL implementations -> Irrelevant


// CLIENT APP
auto mdl = LoadLibrary(...);
auto getSimFunc = GetProcAddress(mdl, ...);
ISimulator* my_sim = getSimFunc();

m_sim->Init(); // << OK
...
...
m_sim->initEnded.hasOccured() // << LNK: Undefined Reference 

用CEvent *代替CEvent的明显解决方案似乎很糟糕,因为它将需要堆分配和适当的销毁,而我倾向于在可能的情况下避免使用

另一种解决方案是使访问CEvent的{​​{1}}的访问者,从而强制进行vtbl调用。

我的问题:我可以强制编译器将CEvent*视为虚拟调用吗?

1 个答案:

答案 0 :(得分:2)

标题显示为“ DLL类导出”,但是在发布的代码中没有导出类。只是将class CEvent更改为class DLL_CLASS_INTERFACE CEvent可能会解决此问题,尽管这不一定是“正确”的解决方案。

另一种方法是不公开initEnded对象本身,而是公开指向它的CEvent *指针,从而使编译器别无选择,只能生成虚拟调用。

但是,如果ISimulator看起来/看起来像是适当的接口,则它不应该公开数据成员。相反,您可以完全隐藏initEnded,然后向ISimulator接口virtual bool InitEndedHasOccurred();添加另一种方法。

相关问题