2010-07-09 55 views
2

我想從C#傳遞一個對象數組到非託管C++,並且沒有任何東西可以工作。如何將Object數組傳遞給非託管代碼?

編譯器不會讓我假裝數組是一個IntPtr。將數組轉換爲IntPtr不起作用。我試圖傳遞固定數據的地址,但這也不起作用。

我只需要將一個指針傳遞給數組的開始,這是難以置信的困難。

任何建議或鏈接?感謝名單!

+0

您如何期望從非託管代碼中看到該數組(即,元素類型是什麼)? – 2010-07-09 18:11:23

+0

我有(希望)在C#和C++兩側的相同的對象定義。被調用函數有一個指向這個類型的指針作爲參數。 – user20493 2010-07-09 18:20:00

+0

你的意思是一個C++類的定義?它不這樣工作。 CLR類的內存中佈局是實現定義的,您無法在C++中匹配它。你可以做的是讓對象實現一些接口,並提供非託管大小的接口的非託管定義,然後讓P/Invoke編組數組。 – 2010-07-09 18:26:25

回答

1

你可以投給一個void指針嗎?確保對象數組是固定的。

+0

我試過了: VariableObject [] varObj = new VariableObject [numVarObjects]; GCHandle pinnedData = GCHandle.Alloc(varObj,GCHandleType.Pinned); IntPtr ptr = pinnedData。AddrOfPinnedObject(); Alloc調用的結果是:「對象包含非原始數據或非可變數據。」。 – user20493 2010-07-09 18:05:03

+0

您無法獲得指向託管類型的指針。託管類型的數組也是託管類型,而對象引用是託管類型。 – 2010-07-09 18:16:20

+0

那麼這個數組如何傳遞給非託管代碼呢? – user20493 2010-07-09 18:17:47

1

什麼終於摸索:

  1. 傳遞結構,而不是對象(引用)的數組的數組。
  2. 在結構定義之前放置「[StructLayout(LayoutKind.Sequential,Pack = 1)]」。
  3. 在字符串之前(在結構定義中)放置「[MarshalAs(UnmanagedType.LPWStr)]」,以使字符串在C++端顯示爲寬字符字符串。
  4. 在DllImport聲明中聲明參數的結構數組:「VariableObject [] varObj」。
  5. 在C++端聲明一個指向類的指針作爲參數。 (C++類映射C#結構。):「VariableObject * varObj」。
0

在你的C#/託管方法簽名,紀念與輸入參數[的MarshalAs(UnmanagedType.LPArray,SizeParamIndex = 0)] ...

[DllImport(...)] 
public void DoTask 
    (
     ..., 
     [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] results, 
     ... 
    ); 

然後調用它像你一樣總是。另外,在非託管代碼中,您可以修改此數組。我建議你發送一個額外的int,告訴非託管代碼該數組的大小是爲了防止「數組越界」修改。

相關問題