2009-04-24 57 views
3

我實際上有兩個unmaged C++庫,其中一個使用另一個。兩者都很大,所以重寫對我來說不是一種選擇。將非託管C++類庫暴露給c#

我讀了一些關於創建託管C++庫的東西,它包圍了非託管代碼。但我真的不知道如何開始,以及如何在一個項目中結合所有這些東西...

是否有任何一步一步的指南或好的容易理解的例子如何做到這一點?

TIA

+1

已經在這裏回答http://stackoverflow.com/questions/761930/getting-object-functionallity-out-of-c-code-in-c/762012#762012以及其他許多帖子;這是最近一個非常普遍的問題。 – 2009-04-27 23:35:02

回答

1

我認爲這取決於您實際需要暴露多少庫函數。

我不知道如何創建一個託管C++包裝,但我個人使用其他兩種方法來解決這個問題:

  1. 使用SWIG自動生成C#PInvoke的包裝爲你的C++類。這類作品,但真的只值得如果你需要公開批次的類和成員。根據我的經驗,自動生成的代碼仍然需要手動調整。

  2. 爲你需要的功能編寫非託管C包裝,從DLL中導出它們,並手動編寫你需要導入到C#中的幾個PInvoke包裝。我發現這在某些情況下更合適,例如有一個大型C++類庫執行不同類型的圖像文件轉換,但您真正想要公開的是一個函數DoTheConversion(LPWSTR inputFile)。我的C#程序不需要知道底層類庫的所有複雜性。

1

您可以在同一個項目中編寫託管和非託管C++。所以你可以在Managed C++中編寫一個包裝器,它調用你的本地C++類等。然後在C#中,託管的C++類將會像其他任何.net引用一樣出現。在這種情況下不需要使用P/Invoke。

1

你有兩個選擇,一個叫做ijw「它只是起作用」,你可以在其中編寫託管C++並調用非託管C++。另一個選項需要使用pinvoke。

,如果你使用的PInvoke你就會有這樣的事情

C#

somefunction("str1", "str2", "str3", "str4"); 

[DllImport(@"myproj.dll", EntryPoint = "somefunction")] 
public static extern IntPtr SomeFunction([MarshalAs(UnmanagedType.LPWStr)]string jarg1, [MarshalAs(UnmanagedType.LPWStr)]string jarg2, [MarshalAs(UnmanagedType.LPWStr)]string jarg3, [MarshalAs(UnmanagedType.LPWStr)]string jarg4); 

C++

extern "C" __declspec(dllexport) void* __stdcall somefunction(wchar_t * jarg1, wchar_t * jarg2, wchar_t * jarg3, wchar_t * jarg4) 
{ 
//do some stuff with strings 
} 

如果你使用SWIG,痛飲會嘗試自動生成上面的代碼,但這是一個苛刻的主人。

我曾經使用託管C++,但我不記得我對它的想法。

3

您可能會考慮使用ATL爲您的C++代碼編寫一個COM包裝器。我展示瞭如何在blog post中做到這一點。這就是Microsoft公開他們使用C++編寫的功能(例如Windows 7 Libraries功能)的方式。 COM很容易被.NET/C#使用(見this post)。如果你走這條路線,你可能會考慮registration free COM,如果你不需要與他人分享你的包裝。