2008-09-19 59 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)分別構建版本。

相關問題