2010-08-26 57 views
2

我喜歡在我的c#應用程序導入c + + dll我怎麼能這樣做?,什麼是我需要使用這個概念?我如何使用c + + dll在c#

+1

Nitpicking:我想你的意思是「非託管DLL」。儘管可以使用C++名稱修飾(這不是標準;它取決於您使用的鏈接器),但DLLs永遠不會「在C++中」。 – tenfour 2010-08-26 10:32:45

回答

1

假設this的DLL編譯MinGW的概念。 在C-鋒利可以遵循這樣的代碼:

using System.Runtime.InteropServices; 
using System; 

class call_dll { 

    [StructLayout(LayoutKind.Sequential, Pack=1)] 
    private struct STRUCT_DLL { 
    public Int32 count_int; 
    public IntPtr ints; 
    } 

    [DllImport("mingw_dll.dll")] 
    private static extern int func_dll(
     int an_int, 
     [MarshalAs(UnmanagedType.LPArray)] byte[] string_filled_in_dll, 
     ref STRUCT_DLL s 
    ); 

    public static void Main() { 

    byte[] string_filled_in_dll = new byte[21]; 


    STRUCT_DLL struct_dll = new STRUCT_DLL(); 
    struct_dll.count_int = 5; 
    int[] ia = new int[5]; 
    ia[0] = 2; ia[1] = 3; ia[2] = 5; ia[3] = 8; ia[4] = 13; 

    GCHandle gch = GCHandle.Alloc(ia); 
    struct_dll.ints = Marshal.UnsafeAddrOfPinnedArrayElement(ia, 0); 

    int ret=func_dll(5,string_filled_in_dll, ref struct_dll); 

    Console.WriteLine("Return Value: " + ret); 
    Console.WriteLine("String filled in DLL: " + System.Text.Encoding.ASCII.GetString(string_filled_in_dll)); 

    } 
} 
+0

這是P/Invoke概念的一個例子。 – 2010-08-26 16:56:01

2

可以訪問的C++庫源

最乾淨的方式是使用C++ Interop創建一個包裝作爲混合模式組件。這使您可以使用託管和非託管的編譯指示在本機代碼和託管代碼之間切換。通過這種方式,您可以很好地將C++類用託管的C++包裝器打包,然後從(當然)託管的C#中調用它。

要知道這不會單下工作。

不能訪問C++庫的源代碼,但知道一些C++嗎?

由於C++獨特的本地調用COM的能力,您可以在託管C++中編寫一個小的託管包裝來調用非託管C++庫。

這是使用custom runtime callable wrappers, or CRCWs完成的。然後,您可以直接使用本機.Net類型和全部來自C#調用您的託管包裝。

的這個好處(如由MSDN說明):

的互操作代碼被內置到應用程序,所以在一個單獨的組件沒有依賴性。此外,暴露的託管界面被定製爲更像.NET。例如,RenderFile方法使用System.String而不是char *。 COM接口的受管版本稱爲自定義運行時可調用包裝器(CRCW)。

不必訪問C++庫源,不知道C++?

然後你被卡住C++ COM Interop這是比較凌亂一點。您需要使用Tlbimp.exe生成封裝。

它的混亂,因爲:

  1. 類型沒有在託管代碼直接匹配被暴露的IntPtr指針類型(很難在C#中處理)
  2. 產生的assemlblies將是非常大的因爲庫中所有東西的接口都會生成(不僅僅是你想要的東西)。
  3. 你必須在你的應用程序中部署一個額外的程序集並管理版本控制等。