如何最好地避免 C++/CLI 本机类型中的双重转换

2024-03-21

传统上,我一直使用 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

** 更新 **

测试的一些更新。

  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);
    };
    

编译完成后,我现在可以从库外部使用调用者类,并且不会导致双重重击。这就是我想要的。然而,我担心这不是正确的方法。我还没有读到任何表明这种方法是安全的。

我真的很想要一些关于如何有效使用混合模式 C++ 库以避免我们所看到的性能影响的指南。

-Nick


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何最好地避免 C++/CLI 本机类型中的双重转换 的相关文章

  • 禁用/启用 MFC 功能包的功能区按钮

    我正在使用 MFC 功能包 并且功能区栏上有一些按钮 即 CMFCRibbonButton 的实例 问题是我想在某些条件下启用和禁用其中一些 但在运行时 我怎样才能做到这一点 因为没有具体的方法 我听说解决方案是在运行时附加 分离事件处理程
  • 想要将 ColeDateTime 转换为 CTime

    我正在从数据库中读取日期时间ColeDateTime格式 我想将其转换为CTime获取日期 月份 年份和时间 CString repDt this will hold the datetime which i read from Datab
  • MFC CMenu 工具提示未显示

    我尝试使用类似的东西来设置 CMenu 项的工具提示 如所述here https stackoverflow com questions 2400180 mfc how to add tooltip in cmenu items 但它只是显
  • _CrtDumpMemoryLeaks( ) == 1 在第一行代码上?

    我正在开发一个 MFC Visual C 项目 据我了解MSDN http msdn microsoft com en us library d41t22sb 28v VS 100 29 aspx CrtDumpMemoryLeaks 应该
  • 获取正在运行的程序的属性

    我想开发一个程序 其 ID 是一张牌 因为它在另一个正在运行的程序 例如扑克或红心游戏或其他程序 中播放 我首先尝试获取有关已运行的游戏程序的所需信息 但我从一开始就遇到了问题 我正在运行 MSVC 2013 并开发 MFC 应用程序 现在
  • 在 C++/CLI 中使用 EventHandler

    我正在尝试使用 c cli 中的事件处理程序来引发事件 然后在 c 中订阅它 class Mclass event System EventHandler someEvent void ShowMessage System String s
  • 如何在 C++/CLI 中显式/隐式实现接口成员?

    在 C CLI 中与此等效的内容是什么 class Explicit IClonable void IClonable Clone class Implicit IClonable public void Clone 正如 nobugz 所
  • 为什么受保护的 C++-Cli 析构函数不会导致编译错误?

    如果我编译并运行以下命令 using namespace System ref class C1 public C1 Console WriteLine L Creating C1 protected C1 Console WriteLin
  • 如何在 MFC 中创建带圆角的进度控件?

    我需要在 MFC 应用程序中创建一个带圆角的进度条 我尝试过使用 CreateRoundRectRgn 和 SetWindowRgn 的组合 它具有使控件完全消失的效果 我还尝试使用透明的 GIF 覆盖层 该覆盖层将绘制在进度栏的顶部 但我
  • 在 C++/CLI 中创建时初始化静态字典

    今天我看到创建静态字典并初始化它的 C 代码 public static readonly Dictionary
  • C++ 中的转换错误

    有人可以帮我解决这个错误吗 我是 C 新手 看来错误就发生在一堆宏中 我能做什么来解决它 或者我怎样才能追踪到它的源头 我真的不明白这个错误 这是否意味着编译器尝试转换该方法void ReadCPUparameter to a LRESUL
  • C++/CLI 中的 RAII

    我已经习惯了 C RAII 工具 并且希望通过 C CLI 中的托管代码以正确的方式使用 RAII Herb http blogs msdn com b hsutter archive 2004 07 31 203137 aspx Sutt
  • C++/CLI 中的 ref 和 out

    我知道 C CLI 代码 void foo Bar x 转变为 Void foo ref Bar x 变成的 C CLI 代码是什么 Void foo out Bar x 您可以使用 OutAttribute using namespace
  • 使用命名空间

    有什么区别 using System and using namespace System 是同一件事吗 thanks 是的 有区别 第一个无法编译 也许你的意思是这样的 using
  • 在运行时将无模式对话框转换为模式对话框

    我有一个对话框 CDialog 派生类 可以以两种不同的方式使用 编辑模式和编程模式 当对话框打开以在编程模式下使用时 它是一个无模式对话框 用于修改主视图 类似于工具栏 当它以编辑模式打开时 用户可以更改对话框本身的配置 在这种情况下 它
  • MFC CImage alpha 混合出错

    我必须在图片控件上呈现由两个 PNG 文件组成的图像 其中顶部图像在某些位置具有透明像素 结果应该是plotter png 与 bar png 顶部重叠显示为 注意条上奇怪的白色轮廓 但应该是 我为它编写的代码很简单 CImage imag
  • 如何将 C++ 类包装在基于 C 的 dll 或基于 CLI 的 dll 中?

    我被告知将我用 C 编写的类导入到 dll 中 然后在 c 应用程序中使用该 dll 下列的本指南 https stackoverflow com questions 4555961 how to use a class in dll我创建
  • MFC:从另一个线程调用 CWnd 方法安全吗?

    其实我有两个问题 打电话安全吗SendMessage来自工作线程 Do CWnd方法 比如MessageBox 调用API函数SendMessage幕后 根据我的理解 当工作线程调用时SendMessage 它将消息推送到UI线程的消息队列
  • 调试器忽略动态加载的 DLL 中的错误

    我有一个与自编码 DLL 的调试相关的非常奇怪的问题 我有一个 MFC 驱动的基于对话框的应用程序 几个静态链接的项目和几个在运行时加载的 DLL 项目 我在调试中构建解决方案 运行应用程序 然后我可以轻松调试这些 DLL 项目 现在问题来
  • 支持 ARM 上的 Windows 10 桌面应用程序 - MFC 和 COM 以及 OPOS 可以工作吗?

    我试图了解将在 x86 Windows 10 上运行的 C MFC 应用程序移植到具有 Qualcomm Snapdragon 处理器的 ARM Windows 10 设备的障碍 32位应用程序具有以下特点 MFC 与 C 用于用户界面 C

随机推荐