2012-11-01 72 views
0

我有一個C++ dll,它有一些extern函數。 和它的外觀像這樣獲取C++指針c#

//C++ Code 
void GetData(byte * pData) 
{ 
    byte a[] = {3,2,1}; 
    pData = a; 
} 

,我有使用此代碼在C#中端得到數據:

//C# Code 
[DllImport(UnmanagedDLLAddress)] 
public static extern void GetData(ref IntPtr pData); 

//and use it like 
IntPtr pointer = IntPtr.Zero; 
GetData(ref pointer); 
byte[] data = new byte[3] // <===== think we know size 
Marshal.Copy(pointer,data ,0,3); 

但總是「指針」是零,因此Marshal.Copy拋出空例外 其中i錯了嗎? ty

+1

即C++代碼有UB。 – Pubby

+0

什麼是字節型? – billz

+0

@Pubby:那我該如何解決? – mX64

回答

5

首先,您的C++代碼將數組放入堆棧。您需要以其他方式進行分配,以便從以下文檔開始:http://msdn.microsoft.com/en-us/library/aa366533%28VS.85%29.aspx

其次,pData是一個「正常」值參數,實際上是一個局部變量。您分配給它,然後它在函數返回時被遺忘。如果你希望它是「out parameter」返回一個值,你需要它是指針或指向指針的指針。如果要真正將陣列內容複製到由pData指向的緩衝區,則需要使用#include <cstring>中的memcpy功能。

+0

ty,我會盡快檢查 – mX64

3

實際上,就像hyde所說的那樣,使用pData作爲「out」參數。 因爲它顯然是一個引用類型而沒有值類型,被調用的方法應該關心內存分配。我只對值類型使用「ref」,如整數 - 例如從非託管方法獲取數組的長度。

這種方式對我來說很好,而且我使用「cdecl」調用約定。

IntPtr aNewIntArray; 
uint aNewIntArrayCount = 0; 

NativeMethods.getEntityFieldIntArray(out aNewIntArray, ref aNewIntArrayCount); 

int[] aNewIntArrayResult = new int[aNewIntArrayCount]; 
Marshal.Copy(aNewIntArray, aNewIntArrayResult, 0, (int)aNewIntArrayCount); 

方法聲明:

[DllImport(SettingsManager.PathToDLL, EntryPoint = "getEntityFieldIntArray", CallingConvention = CallingConvention.Cdecl)] 
public static extern ErrorCode getEntityFieldIntArray(out IntPtr aNewIntArray, ref UInt32 aNewIntArrayCount);