3

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

但是,当 dll 更改为使用 /clr 时,此方法变得昂贵,因为调用可能会导致双重提示。我目前的表现受到了巨大的打击,需要停止双重打击。我所看到的解决方案建议确保一切都使用 __clrcall 约定,但这不适用于 dllexport。

微软自己关于双重思考的部分建议:

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

对我来说,这看起来好像我可以从我的类中删除 dllexport/dllimport 并在我的 stdafx.h 中粘贴一个#using。但是,对于本机类型,这会导致 LNK2028(未解析的令牌)和 LNK2019(未解析的外部符号)。我是否在链接器中包含 .lib 没有区别;我仍然收到此错误。

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

问候

缺口

** 更新 **

测试中的一些更新。

  1. 一旦使用 /clr 编译 dll,本机类型就会发生双重转换(使用 dllexport/dllimport)。

  2. 这可以通过逐个文件关闭 CLR 支持来缓解。这很痛苦,有时本机类型使用 clr 所以这不能在任何地方完成。并且被调用者也必须是本地编译的,它才能工作。

  3. 方法可以标记为 __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++ 库以避免我们所看到的性能损失的指南。

-缺口

4

0 回答 0