2009-04-09 45 views
1

我正在尋找將非結構數組傳遞給非託管C++ dll的正確語法。如何將C++/CLI數組的結構編組爲非託管C++

我的DLL的進口被稱爲像這樣

#define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static 
_DllImport bool _Validation(/* array of struct somehow */); 

在我的客戶端代碼中,我有

List<MyStruct^> list; 
MyObject::_Validation(/* list*/); 

我知道系統:運行:: InteropServices ::元帥有很多有用的方法做這樣的事情,但我不知道要使用哪個。

回答

3

使用StructLayout.Sequential創建託管版本的非託管結構(請確保按照相同的順序)。然後,您應該能夠通過它就像你把它傳遞給任何管理功能(例如,驗證(MYSTRUCT [] pStructs)

例如,假設我們的本地函數有這個原型:

extern "C" { 

STRUCTINTEROPTEST_API int fnStructInteropTest(MYSTRUCT *pStructs, int nItems); 

} 

和本地MYSTRUCT定義如下:

struct MYSTRUCT 
{ 
    int a; 
    int b; 
    char c; 
}; 

然後在C#中,您定義的結構的一個託管版本如下:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] 
public struct MYSTRUCT 
{ 
    public int a; 
    public int b; 
    public byte c; 
} 

和託管原型如下:

[System.Runtime.InteropServices.DllImportAttribute("StructInteropTest.dll", EntryPoint = "fnStructInteropTest")] 
    public static extern int fnStructInteropTest(MYSTRUCT[] pStructs, int nItems); 

然後,您可以調用函數傳遞MYSTRUCT結構數組如下:

static void Main(string[] args) 
    { 
     MYSTRUCT[] structs = new MYSTRUCT[5]; 

     for (int i = 0; i < structs.Length; i++) 
     { 
      structs[i].a = i; 
      structs[i].b = i + structs.Length; 
      structs[i].c = (byte)(60 + i); 
     } 

     NativeMethods.fnStructInteropTest(structs, structs.Length); 

     Console.ReadLine(); 
    } 
1

您可以使用Marshall.StructureToPtr來獲取可以傳遞到本機MyStruct *數組的IntPtr。

但是,我不知道如何直接從列表中做到這一點。我相信你需要將它轉換爲一個數組,並在將它傳遞給本機代碼之前使用pin_ptr(以防止GC移動你的內存)。

相關問題