【问题标题】:Writing .NET object in C?用 C 编写 .NET 对象?
【发布时间】:2009-10-01 09:50:44
【问题描述】:

有没有办法用 C/C++ 编写一个可以从 .NET 使用的对象?我想用一种最简单的方式来做,基本上是用来扩展所有其他语言的,即用 C 编写一个对象,符合语言运行时所需的接口,使用该语言中的对象。

【问题讨论】:

    标签: .net c interop mono


    【解决方案1】:

    如果您使用托管 C++,它会编译为 IL 代码,因此可以直接在任何 .NET 语言中使用。

    对于非托管C/C++代码,需要在.NET代码中使用P/Invoke来调用。

    【讨论】:

    • P/Invoke 效率极低,因为我将大型二进制 BLOB 作为参数传递,而 P/Invoke 需要复制它。我需要的是从我的组件访问 .NET 基础结构,这样我就可以访问数据而无需复制它。托管 C++ 提供了这种东西,但是,我希望它可以与 .NET 和 Mono 一起使用,并且 Mono 不支持托管 C++ :(
    • 换句话说:CLR是否有类似JNI的接口?
    • 如果您希望它在 Mono 中工作,我会尝试 PInvoke 方法并检查性能是否可以接受,然后再花更多时间寻找更优雅的方法。
    • @martin:你真的试过了吗?我已经来回移动了一些相当大的数组,完全没有问题,特别是当我执行复杂度接近 O(n³) 而复制仅为 O(n) 的矩阵-矩阵乘法之类的操作时。
    【解决方案2】:

    如果 P/Invoke 或 C++/CLI 不适合您的任务,您可以使用 .NET 中的 COM 支持。

    这是一个示例:

    C++ part

    C# part

    它适用于 MS.NET 和 Mono。

    【讨论】:

      【解决方案3】:

      您需要使用 C++/CLI(以前称为托管 C++,但我认为该术语已被微软的营销人员弃用)。

      C++/CLI 是一个 C++ 超集,可编译为 .NET IL 并提供允许与其他 .NET 语言互操作的功能。

      C++/CLI 允许混合托管代码和本机代码。它是唯一支持该功能的 .NET 语言。

      【讨论】:

        【解决方案4】:

        两种方式:

        C++/CLI: C++/CLI 是一种使事物可桥接的方法。您在 C++/CLI 中为 CLI 创建的类并不完全是常规的旧 C++ 类,但您可以将 C++ 类与适配器模式桥接(注意那些 SEHExceptions!)

        P/调用: 如果您想使用基本的本机 C/C++ 库进行开发,您可以使用 P/Invoke 从 CLR 访问任何标准 C 导出,并且如果您在两边都正确声明它们,您可以手动编组您的对象。有关您可能想知道的更多信息,请参阅“Interop with Native Libraries”指南。

        我怎么强调都不过分。注意你的异常!不要让他们从你的 CLI 代码逃到你的本地代码或从你的本地代码逃到他们的 CLI 代码。

        【讨论】:

          【解决方案5】:

          您可以在 C/C++ 中创建一个库,然后通过 P/Invoke 导出方法并在 .NET 中使用它。

          【讨论】:

            【解决方案6】:

            Mono cannot currently compile C++/CLI,不幸的是,虽然 C++/CLI 可能是执行您所要求的最有效和最直接的方法,但它可能不适合您。您可以使用 .NET 工具编译 C++/CLI 程序集,也许是 but even that may not work 好吧(向下滚动到有关“我可以执行我的 Visual Studio .NET 程序...”的答案)。

            P/Invoke 或 COM 互操作应该做到这一点,尽管 P/Invoke 带有潜在的性能问题,并且 COM 互操作意味着您需要将以前简单的 vanilla C 接口转换为 COM 接口......在 C 中,是不是很愉快。

            【讨论】:

              【解决方案7】:

              如果您正在使用unmanaged types (ECMA-334 §27.2),例如原始类型数组,您可以执行以下操作。由于这牺牲了相当多的代码安全性,我强烈建议首先尝试替代方案,并且只有在 P/Invoke 在调试器外部的发布版本中证明速度很慢时才使用此方法(调试器使用much slower P/Invoke (100x slower) 来捕获多种故障)。

              [DllImport("NativeLibrary.dll")]
              private extern unsafe void NativeMethod(byte* data, int length);
              
              byte[] data = new byte[10000000];
              unsafe
              {
                  fixed (byte* ptr = data)
                  {
                      NativeMethod(ptr, data.Length);
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 2010-12-14
                • 2011-03-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-04-02
                相关资源
                最近更新 更多