2008-09-19 79 views
25

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

回答

12
[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您的装配。 Regasm将添加必要的注册表项,以使.NET组件可以看作COM组件。之后,您可以像使用其他COM组件一样调用C++中的.NET组件。

+1

这是一个教程,同时显示C++部分:[如何从Visual Studio.NET或Visual Studio 2005中的本地Visual C++代码调用托管DLL](http://support.microsoft.com/kb/zh-cn/ 828736) – 2012-08-12 08:58:10

+0

我永远不会使用COM。这是非常尴尬和笨拙。我会在C++代码中导出一个函数,而在.NET中使用GetProcAddress()来找到这个入口点并简单地调用它。您甚至可以使用委托实现从C++代码到.NET的回调。 (https://code.msdn.microsoft.com/windowsapps/Enumerate-top-level-9aa9d7c1) – Elmue 2015-02-11 17:55:20

0

您可以将.NET组件包装在一个COM组件中 - 这对.NET工具来说非常简单 - 并通过COM调用它。

0

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

你可以看看这blog得到一些具体的细节。

0

正常创建.NET程序集,但一定要用ClassInterface(ClassInterfaceType.AutoDual)标记类,并确保将程序集信息SetAssemblyAtribute设置为ComVisible(true)。

然后,创建REGASM的COM包装:

regasm MYDLL.DLL /tlb:mydll.tbl /代码库F:_CODE \ ClassLibraryForCom

一定要使用/基本代码指令 - 这是如果你不打算给大会一个强有力的名字,这是必要的。

RP

+0

梅森迪克森警告不要使用ClassInterfaceType.AutoDual http://blogs.msdn.com/mbend/archive/2007/04/17/classinterfacetype-none-is-my-recommended-option-over-autodispatch-autodual .aspx – cwick 2008-09-19 23:06:18

0

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

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

而且,这里是类型互操作的,你可以托管和非托管代码之间做的完整列表:

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

一言以蔽之:

(a)使用COM-互操作

(b)利用进口/ PInvoke的(显式方法调用)

(c)中IJW和MC++应用程式:MC++ & IJW应用程序可以自由地相互来回调用。 (d)主持。这很少见,但CLR可以由非托管应用程序托管,这意味着运行时会调用一堆托管回调。

0

如果您的流程中既可以包含托管代码,也可以包含非托管代码,那么您可以使用虚拟函数创建一个C++类。用混合模式C++/CLI实现类。将实现注入到C++代码中,以便可以从(低级别)C++代码调用(高级)实现。

13

你应该看看C++/CLI。它使这样的任务几乎微不足道。否则,你将不得不围绕C#代码生成COM包装,并让你的C++应用程序调用COM包装。

0

我发现这个链接嵌入单声道: http://www.mono-project.com/Embedding_Mono

它提供了什么似乎是与组件的交互一个非常简单的接口。这可能是一个有吸引力的选择,特别是如果你想跨平台

4

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

使用C++的动机是什么?如果它只是风格,那么你可能会发现你可以用C++/CLI编写所有东西。如果是性能,那么在托管C++和非托管代码之间来回调用是相对直接的。但它永远不会透明。您无法首先将托管指针传递给非托管代码,而无需固定它,以便垃圾回收器不会移动它,当然,非托管代码不会知道您的托管类型。但托管(C++)代码可以知道您的非托管类型。

还有一点需要注意的是,包含非托管代码的C++/CLI程序集将是体系结构特定的。您需要为x86和x64(和IA64)分别构建版本。

相关问题