【问题标题】:C++ DLL Class Export, compiler "optimizes" virtual call [closed]C++ DLL 类导出,编译器“优化”虚拟调用 [关闭]
【发布时间】:2020-10-19 06:25:40
【问题描述】:

我正在创建一个 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 进行访问,该访问器返回CEvent*,从而强制进行vtbl 调用。

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

【问题讨论】:

标签: c++ c dll dllimport


【解决方案1】:

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

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

但是,如果ISimulator 看起来/工作起来像一个适当的接口,那么它不应该一开始就暴露数据成员。相反,您可以完全隐藏initEnded,并在ISimulator 接口virtual bool InitEndedHasOccurred(); 中添加另一个方法。

【讨论】:

    猜你喜欢
    • 2019-04-29
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多