【问题标题】:How do I call C++/CLI (.NET) DLLs from standard, unmanaged non-.NET applications?如何从标准的非托管非 .NET 应用程序调用 C++/CLI (.NET) DLL?
【发布时间】:2011-02-20 14:23:11
【问题描述】:

在非托管世界中,我能够编写 __declspec(dllexport) 或者使用 .DEF 文件来公开函数以调用 DLL。 (由于 __stdcall 在 C++ 中的名称修改,我将别名放入 .DEF 文件中,以便某些应用程序可以重用某些导出的 DLL 函数。)现在,我对能够从.NET 程序集,以非托管方式,但让它进入 DLL 中的 .NET 样式函数。这是否可能,以一种简单直接的方式?

我拥有的是一个第三方程序,我通过实现一些复杂数学的 DLL(插件)扩展了它。但是,第三方程序无法让我可视化计算。我想以某种方式获取这些预先编写的数学函数,将它们编译成一个单独的 DLL(但在 .NET 中使用 C++/CLI),然后在函数中添加挂钩,以便我可以在 .NET 中渲染引擎盖下发生的事情用户控制。我不确定如何将 .NET 的东西与非托管的东西混合在一起,或者 Google 用什么来完成这项任务。

有关托管/非托管桥的具体建议,或以我描述的方式完成呈现的替代方法会有所帮助。谢谢。

【问题讨论】:

    标签: .net user-controls c++-cli managed


    【解决方案1】:

    嗯,C++/CLI 编译器让它变得非常简单。只需编写一个静态托管函数并使用 __declspec(dllexport) 对其进行归因。编译器会注入一个自动加载 CLR 以执行托管代码的存根。

    这是一种有用的方法,它的可扩展性不是很好,也不会很快。下一步是编写一个带有 [ComVisible(true)] 属性的 ref 类。使用 Regasm.exe 注册后,任何非托管 COM 感知客户端都可以使用该服务器。自己托管 CLR (CorBindToRuntimeEx) 通常是最后的选择,但也是最通用的选择。


    示例代码:

    ref class ManagedClass {
    public:
      static void StaticFunc() {}
    };
    
    extern "C" __declspec(dllexport)
    void __stdcall UnmanagedFunc() {
      ManagedClass::StaticFunc();
    }
    

    【讨论】:

    • 如果我需要名称上的 __stdcall 并且想要摆脱名称上的 @number 并需要在 .DEF 文件中创建别名,在这种情况下我该怎么做?我需要的是一个外部“C”风格的签名,这样它就可以被特定类型的第三方应用程序调用。
    • 只需在导出时使用 extern "C" 和 __stdcall 声明符。您不需要 .def 文件。示例已发布。
    • @HansPassant “编译器注入存根”是什么意思?编译器是否生成 .lib(并且 UnmanagedFunc() 的调用者需要与该 lib 链接)?
    • C++ 编译器会自动生成大量魔法代码。这是编译器的工作,它使看似非常困难的代码看起来很容易。虚拟基类的多重继承,这就是火箭科学。那个存根,容易多了。
    【解决方案2】:

    您使用 C++/CLI 是因为您想要,还是因为您认为必须导出函数?

    如果是后者,请查看我的unmanaged exports,它允许您在 C# 中声明非托管导出,这与 DllImport 的工作方式相同。

    internal class Sample
    {
      [DllExport("_export_test", CallingConvention.Cdecl)]
      static int Test(int a)
      {
         return a + 1;
      }
    }
    

    【讨论】:

    • 我想使用 C++/CLI,因为第三方库只需使用 /clr 选项就会自动编译。然后在 .NET 框架中添加插件会使生活变得更好(我认为)。您的示例似乎是一种合理的方法。谢谢。
    • 我不确定我是否在关注你。当您使用我的项目模板时,它也会自动编译(它甚至会创建一个 .lib 文件)。除非我误解了你,而你实际上想使用 C++/CLI。
    【解决方案3】:

    这篇 CodeProject 文章很好地解释了这个过程。

    在非托管应用程序中使用托管代码
    http://www.codeproject.com/KB/mcpp/ijw_unmanaged.aspx

    另请参阅 here 和 here。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 2012-11-19
      • 2010-10-08
      相关资源
      最近更新 更多