传统上,我一直使用 MFC 扩展 dll 并使用 dllimport/dllexport 导入/导出。
但是,当 dll 更改为使用 /clr 时,此方法的成本会变得很高,因为调用可能会导致双重转换。我现在的性能受到了巨大的打击,需要停止双重重击。我见过的解决方案描述建议确保所有内容都使用 __clrcall 约定,但这不适用于 dllexport。
微软自己关于双重思考的部分建议:
同样,如果导出(dllexport、dllimport)托管函数,则会生成本机入口点,并且导入和调用该函数的任何函数都将通过本机入口点进行调用。为了避免在这种情况下出现双重转换,请不要使用本机导出/导入语义;只需通过 #using 引用元数据(请参阅#using 指令 (C++))。
对我来说,这看起来好像我可以从我的类中删除 dllexport/dllimport 并在我的 stdafx.h 中添加 #using 。但是,对于本机类型,这会导致 LNK2028(无法解析的令牌)和 LNK2019(无法解析的外部符号)。无论我是否在链接器中包含 .lib 都没有什么区别;我仍然收到此错误。
所以,我的问题是如何最好地避免双重转换并从 C++/CLI 库导入本机类型?
Regards
Nick
** 更新 **
测试的一些更新。
一旦使用 /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);
};
编译完成后,我现在可以从库外部使用调用者类,并且不会导致双重重击。这就是我想要的。然而,我担心这不是正确的方法。我还没有读到任何表明这种方法是安全的。
我真的很想要一些关于如何有效使用混合模式 C++ 库以避免我们所看到的性能影响的指南。
-Nick
None
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)