如何从C / C ++调用.NET程序集?

假设我正在用C ++和C#编写应用程序。 我想用C ++编写低级部分并在C#中编写高级逻辑。 如何从我的C ++程序加载.NET程序集并开始调用方法并访问我的C#类的属性?

[Guid("123565C4-C5FA-4512-A560-1D47F9FDFA20")] public interface IConfig { [DispId(1)] string Destination{ get; } [DispId(2)] void Unserialize(); [DispId(3)] void Serialize(); } [ComVisible(true)] [Guid("12AC8095-BD27-4de8-A30B-991940666927")] [ClassInterface(ClassInterfaceType.None)] public sealed class Config : IConfig { public Config() { } public string Destination { get { return ""; } } public void Serialize() { } public void Unserialize() { } } 

在那之后,你需要重新assembly你的assembly。 Regasm将添加必要的注册表项,以允许将.NET组件视为COM组件。 之后,您可以使用与其他任何COM组件相同的方式在C ++中调用.NET组件。

你应该真正研究C ++ / CLI。 它使这样的任务几乎无足轻重。

否则,您将必须围绕C#代码生成COM包装器,并让您的C ++应用程序调用COM包装器。

我肯定会为此调查C ++ / CLI并避免COM和所有注册麻烦。

使用C ++的动机是什么? 如果它只是样式,那么您可能会发现可以用C ++ / CLI编写所有内容。 如果是性能,那么在托管C ++和非托管代码之间来回调用是相对简单的。 但它永远不会透明。 您不能先将托管指针传递给非托管代码而不固定它,以便垃圾收集器不会移动它,当然非托管代码也不会知道您的托管类型。 但托管(C ++)代码可以了解您的非托管类型。

另外需要注意的是,包含非托管代码的C ++ / CLI程序集将是特定于体系结构的。 您将需要x86和x64(以及IA64)的分离构建。

您可以将.NET组件包装在COM组件中 – 使用.NET工具非常容易 – 并通过COM调用它。

如果C ++中的低级部分通常是从C#代码中调用,则传入所需的值。 这应该以你可能习惯的标准方式工作。 例如,您需要阅读编组。

您可以查看此博客以获取一些具体细节。

像往常一样创建.NET程序集,但一定要使用ClassInterface(ClassInterfaceType.AutoDual)标记该类,并确保程序集信息SetAssemblyAtribute为ComVisible(true)。

然后,使用REGASM创建COM包装器:

regasm mydll.dll /tlb:mydll.tbl / codebase f:_code \ ClassLibraryForCom

一定要使用/ codebase指令 – 如果你不打算给程序集一个强名字,这是必要的。

RP

由于C#可以导入C ++标准导出,因此在C#应用程序中加载C ++ dll而不是使用C ++中的COM可能更容易。

请参阅System.Runtime.InteropServices.DllImport的文档。

此外,以下是您可以在托管代码和非托管代码之间执行的Interop类型的完整列表:

http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx

简而言之:

(a)使用COM-Interop

(b)使用import / pinvoke(显式方法调用)

(c)IJW和MC ++应用程序:MC ++和IJW应用程序可以相互自由地来回呼叫。

(d)主持。 这种情况很少见,但CLR可以由非托管应用程序托管,这意味着运行时会调用一堆托管回调。

如果在进程中可以同时拥有托管代码和非托管代码,则可以使用虚函数创建C ++类。 使用混合模式C ++ / CLI实现类。 将实现注入到C ++代码中,以便可以从(低级)C ++代码中调用(高级)实现。

我找到了嵌入Mono的链接: http : //www.mono-project.com/Embedding_Mono

它提供了与程序集交互似乎非常简单的界面。 这可能是一个有吸引力的选择,特别是如果你想要跨平台