我實際上有兩個unmaged C++庫,其中一個使用另一個。兩者都很大,所以重寫對我來說不是一種選擇。將非託管C++類庫暴露給c#
我讀了一些關於創建託管C++庫的東西,它包圍了非託管代碼。但我真的不知道如何開始,以及如何在一個項目中結合所有這些東西...
是否有任何一步一步的指南或好的容易理解的例子如何做到這一點?
TIA
我實際上有兩個unmaged C++庫,其中一個使用另一個。兩者都很大,所以重寫對我來說不是一種選擇。將非託管C++類庫暴露給c#
我讀了一些關於創建託管C++庫的東西,它包圍了非託管代碼。但我真的不知道如何開始,以及如何在一個項目中結合所有這些東西...
是否有任何一步一步的指南或好的容易理解的例子如何做到這一點?
TIA
我認爲這取決於您實際需要暴露多少庫函數。
我不知道如何創建一個託管C++包裝,但我個人使用其他兩種方法來解決這個問題:
使用SWIG自動生成C#PInvoke的包裝爲你的C++類。這類作品,但真的只值得如果你需要公開批次的類和成員。根據我的經驗,自動生成的代碼仍然需要手動調整。
爲你需要的功能編寫非託管C包裝,從DLL中導出它們,並手動編寫你需要導入到C#中的幾個PInvoke包裝。我發現這在某些情況下更合適,例如有一個大型C++類庫執行不同類型的圖像文件轉換,但您真正想要公開的是一個函數DoTheConversion(LPWSTR inputFile)
。我的C#程序不需要知道底層類庫的所有複雜性。
閱讀一些文章可能是一個開始 - 這是一個相當廣泛的主題,並沒有「完美」的方式來做到這一點:
http://www.ondotnet.com/pub/a/dotnet/2004/03/29/mcpp_part3.html http://www.codeguru.com/cpp/cpp/cpp_managed/interop/article.php/c6867
這些方法都沒有使用p/invoke,這是我們在我需要接口一個瘋狂的舊C++ - 服務庫的項目中使用的一種方法。
您可以在同一個項目中編寫託管和非託管C++。所以你可以在Managed C++中編寫一個包裝器,它調用你的本地C++類等。然後在C#中,託管的C++類將會像其他任何.net引用一樣出現。在這種情況下不需要使用P/Invoke。
你有兩個選擇,一個叫做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++,但我不記得我對它的想法。
您可能會考慮使用ATL爲您的C++代碼編寫一個COM包裝器。我展示瞭如何在blog post中做到這一點。這就是Microsoft公開他們使用C++編寫的功能(例如Windows 7 Libraries功能)的方式。 COM很容易被.NET/C#使用(見this post)。如果你走這條路線,你可能會考慮registration free COM,如果你不需要與他人分享你的包裝。
已經在這裏回答http://stackoverflow.com/questions/761930/getting-object-functionallity-out-of-c-code-in-c/762012#762012以及其他許多帖子;這是最近一個非常普遍的問題。 – 2009-04-27 23:35:02