2014-06-06 69 views
0

所以我在C#中爲C DLL寫封裝。問題是一些功能使用複雜數據類型例如爲:C#dllimport跨平臺的複雜數據類型?

ComplexType* CreateComplexType(int a, int b); 

有沒有一種方法,我可以宣佈一個有效的C#類,這樣我可以使用dllimport的? 如果我在做一個純Windows的解決方案,我可能會使用C++/CLI作爲本地複雜類型和託管複雜類型之間的中介。

我確實可以訪問C dll的源代碼,那麼是否可以使用不透明類型(例如句柄)?

回答

0

對於在Windows和Linux中使用P/Invoke,單聲道有很好的documentation page。具體來說,請參閱封送處理部分,討論簡單類型和複雜類型。如果你想創造性,你可以將你的類型序列化爲一些方便的基於字符串的格式,如JSON或XML,並將其用作編組機制。

1

這樣的功能很難從C程序中可靠地調用,但在拼貼時它不會變得更好。問題在於內存管理,那個結構需要被再次銷燬。這要求調用程序使用與DLL相同的內存分配器。這在C程序中很少出現,但您可能很幸運擁有DLL的源代碼,因此您可以重新編譯它並確保每個人都使用相同的共享CRT版本。

當然,C#沒有這樣的運氣,pinvoke編組會調用CoTaskMemFree()來釋放結構。很少有真正的C程序使用CoTaskMemAlloc()來分配結構,因此這是XP的無聲故障,Vista和更高版本的AccessViolationException。現代Windows版本有一個更嚴格的堆管理器,不會忽略無效指針。

您可以聲明返回值爲IntPtr,即停止拼接編組器試圖銷燬它。然後用Marshal.PtrToStructure()手動編組。這不會阻止內存泄漏,您的程序最終會與OOM崩潰。無論如何。