Mfc 如何最好地避免C++/CLI本机类型

Mfc 如何最好地避免C++/CLI本机类型,mfc,c++-cli,Mfc,C++ Cli,传统上,我一直使用MFC扩展dll,并使用dllimport/dllexport导入/导出 但是,当dll更改为使用/clr时,此方法的成本会很高,因为调用可能会导致双重thunk。我现在的表现受到了巨大的打击,需要停止这种双重打击。我看到的解决方案建议确保所有内容都使用_clrcall约定,但这不适用于dllexport 微软自己关于双重重击的章节建议: 类似地,如果导出(dllexport、dllimport)托管函数,则会生成本机入口点,并且导入和调用该函数的任何函数都将通过本机入口点进行

传统上,我一直使用MFC扩展dll,并使用dllimport/dllexport导入/导出

但是,当dll更改为使用/clr时,此方法的成本会很高,因为调用可能会导致双重thunk。我现在的表现受到了巨大的打击,需要停止这种双重打击。我看到的解决方案建议确保所有内容都使用_clrcall约定,但这不适用于dllexport

微软自己关于双重重击的章节建议:

类似地,如果导出(dllexport、dllimport)托管函数,则会生成本机入口点,并且导入和调用该函数的任何函数都将通过本机入口点进行调用。为了避免在这种情况下出现双重碰撞,请不要使用本机导出/导入语义;只需通过#using(参见#using指令(C++))引用元数据即可

对我来说,这就好像我可以从类中删除dllexport/dllimport,并在stdafx.h中使用a#using。但是,对于本机类型,这将导致LNK2028(未解析的令牌)和LNK2019(未解析的外部符号)。无论我是否在链接器中包含.lib都没有区别;我仍然得到这个错误

所以,我的问题是,如何最好地避免双重碰撞并从C++/CLI库导入本机类型

问候

尼克

**更新**

测试中的一些更新

  • 一旦使用/clr编译dll,本机类型就会发生双重重击(使用dllexport/dllimport)

  • 这可以通过逐个文件关闭CLR支持来缓解。这是一个难题,有时本机类型使用clr,所以这不能在任何地方都实现。被调用方也必须编译为本机才能工作

  • 方法可以标记为uu 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);
    };
    
  • 这将编译,我现在可以从库外部使用caller类,并且不会导致双重的thunk。这就是我想要的。然而,我担心这不是解决问题的方法;我没有读到任何东西表明这种方法是安全的

    我真的很想知道如何有效地使用混合模式C++库来避免我们所看到的类似性能。
    -尼克

    很不清楚你为什么认为自己有这个问题。如果您从MFC代码调用C++/CLI代码,那么您必须发出声音。我们的基本库中我自己的一个类(使用MFC)被调用了大约一百万次。我们看到了大量零星的性能问题,并且启动了分析器,我可以看到在这个链的底部有一个砰砰声。这个thunk比方法调用花费的时间更长。我已经开始在这个地方撒上pragma managed(push,off)来加快本地代码的速度。在某种程度上,这是可行的,但很难看,也很难维持。正如最初发布的,MS建议您不应该使用dllexport/dllimport,但我无法让其他方法工作。我应该补充一点-这是一个混合模式dll,但所讨论的类是一个本机类。当从库外部调用时,会发生双重重击。