传统上,我一直在使用 MFC 扩展 dll 并使用 dllimport/dllexport 导入/导出。
但是,当 dll 更改为使用 /clr 时,此方法变得昂贵,因为调用可能会导致双重提示。我目前的表现受到了巨大的打击,需要停止双重打击。我所看到的解决方案建议确保一切都使用 __clrcall 约定,但这不适用于 dllexport。
微软自己关于双重思考的部分建议:
同样,如果您导出 (dllexport, dllimport) 托管函数,则会生成本机入口点,并且任何导入和调用该函数的函数都将通过本机入口点进行调用。为避免在这种情况下出现双重提示,请不要使用本机导出/导入语义;只需通过#using 引用元数据(参见#using Directive (C++))。
对我来说,这看起来好像我可以从我的类中删除 dllexport/dllimport 并在我的 stdafx.h 中粘贴一个#using。但是,对于本机类型,这会导致 LNK2028(未解析的令牌)和 LNK2019(未解析的外部符号)。我是否在链接器中包含 .lib 没有区别;我仍然收到此错误。
所以,我的问题是如何最好地避免双重打击并从 C++/CLI 库中导入本机类型?
问候
缺口
** 更新 **
测试中的一些更新。
一旦使用 /clr 编译 dll,本机类型就会发生双重转换(使用 dllexport/dllimport)。
这可以通过逐个文件关闭 CLR 支持来缓解。这很痛苦,有时本机类型使用 clr 所以这不能在任何地方完成。并且被调用者也必须是本地编译的,它才能工作。
方法可以标记为 __clrcall,但与 dllexport 混合时会导致编译错误。但是,我设法使以下代码在没有双重提示的情况下工作:
// MFCCLRLIB_API is defined in the library only (as dllexport) // but NOT defined when using (dllimport) // MFCCLRLIB_CALL is defined as empty in the library, // but __clrcall when using. #ifndef _MFCCLRLIB #define MFCCLRLIB_API #define MFCCLRLIB_CALL __clrcall #endif class MFCCLRLIB_API ThunkHack { public: ThunkHack(); ThunkHack(const ThunkHack&); ~ThunkHack(); }; class MFCCLRLIB_API ThunkHackCaller { public: ThunkHackCaller(void); ~ThunkHackCaller(void); virtual void MFCCLRLIB_CALL UseThunkClass(ThunkHack thunk); };
这可以编译,我现在可以从库外部使用调用者类,它不会导致双重 thunk。这就是我想要的。但是,我担心这不是这样做的方法。我没有读过任何表明这种方法是安全的。
我真的很想要一些关于如何有效使用混合模式 C++ 库以避免我们所看到的性能损失的指南。
-缺口