如何从C / C ++调用.NET程序集?
假设我正在用C ++和C#编写应用程序。我想用C ++编写低级部分,并用C#编写高级逻辑。如何从C ++程序加载.NET程序集并开始调用方法并访问Cclass的属性?
解决方案
我们可以将.NET组件包装到COM组件中,而使用.NET工具则很容易,然后通过COM进行调用。
如果是C ++中的低级部分,那么通常我们会从Ccode中调用它,并传入所需的值。这应该以我们可能习惯的标准方式工作。例如,我们需要阅读有关编组的知识。
我们可以查看此博客以获取一些具体细节。
正常创建.NET程序集,但请确保使用ClassInterface(ClassInterfaceType.AutoDual)标记该类,并确保将程序集信息SetAssemblyAtribute设置为ComVisible(true)。
然后,使用REGASM创建COM包装器:
regasm mydll.dll /tlb:mydll.tbl / codebase f:_code \ ClassLibraryForCom
请确保使用/ codebase指令-如果我们不想给程序集起一个强名,则很有必要。
rp
[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() { } }
之后,我们需要重新组装组件。 Regasm将添加必要的注册表项,以使.NET组件被视为COM组件。之后,我们可以用C ++调用.NET组件,方法与其他任何COM组件相同。
由于Ccan可以导入C ++标准导出,因此将C ++ dll加载到C应用程序中可能比使用来自C ++的COM更容易。
请参阅有关System.Runtime.InteropServices.DllImport的文档。
另外,这是我们可以在托管代码和非托管代码之间执行的Interop类型的完整列表:
http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx
简而言之:
(a)使用COM-Interop
(b)使用导入/调用(显式方法调用)
(c)IJW和MC ++应用程序:MC ++和IJW应用程序可以相互自由地来回调用。
(d)托管。这种情况很少见,但是CLR可以由非托管应用托管,这意味着运行时将调用大量托管回调。
如果流程中可以同时包含托管代码和非托管代码,则可以创建带有虚函数的C ++类。用C ++ / CLI混合模式实现该类。将实现注入到C ++代码中,以便可以从(低级)C ++代码中调用(高级)实现。
我们应该真正研究C ++ / CLI。它使这样的任务变得微不足道。
否则,我们将必须围绕Ccode生成COM包装器,并让C ++应用程序调用COM包装器。
我发现此链接嵌入了Mono:
http://www.mono-project.com/Embedding_Mono
它提供了一个似乎很简单的与程序集交互的界面。这可能是一个有吸引力的选择,尤其是如果我们想跨平台
我一定会为此调查C ++ / CLI,避免COM和所有可能产生的注册麻烦。
使用C ++的动机是什么?如果只是样式,那么我们可能会发现可以用C ++ / CLI编写所有内容。如果是性能,那么在托管C ++和非托管代码之间来回调用是相对简单的。但这永远不会是透明的。我们不能先将托管指针传递给非托管代码而不将其固定,以使垃圾收集器不会移动它,当然非托管代码也不会知道托管类型。但是托管(C ++)代码可以知道非托管类型。
需要注意的另一件事是,包含非托管代码的C ++ / CLI程序集将特定于体系结构。我们将需要针对x86和x64(和IA64)的单独构建。