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

时间:2020-03-06 14:28:03  来源:igfitidea点击:

假设我正在用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)的单独构建。