【问题标题】:Using a Very C# DLL in C++在 C++ 中使用非常 C# 的 DLL
【发布时间】:2011-07-28 00:12:41
【问题描述】:

我正在尝试使用 C# DLL,它在 Embarcadero C++ Builder 中具有对 .NET 类和 C# 类的多个引用。 诸如 Point 类和 String 类以及 Delegates 之类的东西。

我想知道 >NET 引用或 C# 引用是否会以某种方式搞砸我。我正要把它连接起来,但我想知道我遇到的一些问题是否可能是由于 C++ 不想玩得好。

【问题讨论】:

  • 挂上它,当工作时回来。

标签: c# c++ dll c++builder


【解决方案1】:

您需要使用 C++/CLI 在 C++ 中使用任何 .NET 内容。您也可以设置自己的 AppDomain,但只有这两种选择,因为 C++ 根本没有与 .NET 交互的本机能力。

【讨论】:

    【解决方案2】:

    或者你可以use the mono CLR embedder

    托管代码可以通过两种方式调用非托管代码,[使用 P/Invoke 或]使用low-level Mono embedding API

    这很像在 C/C++ 可执行文件中嵌入 Perl、Python 或 Ruby“解释器”(实际上是虚拟机)的老式嵌入。我认为实际上(还)没有 Swig(++) 包装器生成器之类的东西,但这里有一个对 CIL 代码的调用的 sn-p:

     class MyClass {
        static void Foo (int value) {
          ...
        }
    
        int Bar (string name) {
          ...
        }
      }
    

    假设您在 foo_method 和 bar_method 中获得了相应的 MonoMethod*,并且 this_arg 是 MyClass 类型的 MonoObject*,您只需执行:

      /* we execute methods that take one argument */
      void *args [1];
      int val = 10;
      /* Note we put the address of the value type in the args array */
      args [0] = &val;
    
      /* execute Foo (10);
       * it's a static method, so use NULL as the second argument.
       */
      mono_runtime_invoke (foo_method, NULL, args, NULL);
    
      /* a string is a reference, so we put it directly in the args array */
      args [0] = mono_string_new (domain, "Hello");
      /* execute my_class_instance.Bar ("Hello");
       * See the Creating Objects section to learn how to get this_arg.
       */
      MonoObject *result = mono_runtime_invoke (bar_method, this_arg, args, NULL);
      /* we always get a MonoObject* from mono_runtime_invoke (), so to get
       * the integer value we need to unbox (which returns a pointer to
       * the value stored in the object) and dereference.
       */
      int int_result = *(int*)mono_object_unbox (result);
    

    为了额外的娱乐价值:如果您对所有 CIL 代码进行 AOT 编译,您将能够将您的程序集静态链接您的本机二进制文件(有效地做托管 C++ (c++-cli) 称为混合模式程序集的内容)。看看

     mono --aot=static myassembly.dll
    

     mkbundle
    

    【讨论】:

    • 在这种情况下,它是非托管代码调用托管代码,这排除了 p/invoke。
    • 没关系,你收到剩下的信息了吗?两种方式都支持:)
    • 我很好奇,如何使用 P/Invoke 从原生 C++ 代码调用 C# 代码?
    • 我也很好奇。为什么我有一个 20 多行代码 sn-p、2 个 Web 引用,专门用于从 C++ 代码调用 C#,但所有评论者都偶然发现了 SINGLE 单词 P/Invoke?我想我会不加粗的,因为我们所有的编程短注意力跨度读者什么都看不到......
    • 它仍然有一两个错误。我似乎只能使用该网站的工具创建一个功能齐全的 TLB,而不是 Embarcadero 的导入功能。或多或少相同的输出,但过程稍微复杂一些。一旦我弄清楚为什么/把它整理出来,我会发布一个完整的答案。
    【解决方案3】:

    我在this question 中为您的问题提供了类似的answer

    您基本上需要 C# 代码的 C++/CLI 接口。

    如果您想将 C# 委托传递给 C++ 代码,可以使用 Marshal::GetFunctionPointerForDelegate() (MSDN) 对其进行翻译。这会给你一个IntPtr,你可以调用ToPointer()作为函数指针传入。

    【讨论】:

    • 有趣,更轻量级的方法。主动权必须来自 C#,但您可以将控制权转移回本机代码并使用 callbakcs。可能很有用,谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多