2012-04-17 54 views
3

我有一個本地方法,必須提供一個字節數組到.NET包裝。該natove方法看起來像:IntPtr不包含本地值

__declspec(dllexport) int WaitForData(unsigned char* pBuffer) 
{ 
    return GetData(pBuffer); 
} 

的GetData分配使用malloc和拷貝一些數據(字節流)到它的存儲器區域。這個字節流是通過套接字連接接收的。返回值是pBuffer的長度。

該方法必須從.NET調用。進口申報如下所示:

[DllImport("CommunicationProxy.dll")] 
public static extern int WaitForData(IntPtr buffer); 

[編輯]

將在P/Invoke的互操作助理,即dasblinkenlight建議,翻譯原型以下進口簽名:

public static extern int WaitForData(System.IntPtr pBuffer) 

結果是一樣的:調用該方法後,ptr爲0。

[/編輯]

Atfer所述方法被調用,結果被提取:

IntPtr ptr = new IntPtr(); 
int length = Wrapper.WaitForData(ref ptr); 

byte[] buffer = new byte[length]; 
for(int i = 0;i<length;i++) 
{ 
    buffer[i] = System.Runtime.InteropServices.Marshal.ReadByte(ptr, i); 
} 
Wrapper.FreeMemory(ptr); 

的問題是,被管理的可變PTR不包含的值與天然變量pBuffer包含。 ptrWrapper.WaitForData返回時始終爲0,儘管pBuffer指向分配的內存區域。

原型有錯誤嗎?如何編組一個字節數組的指針?

+0

我幾乎可以確定'DllImport'簽名是不正確的。看看[這篇文章](http://msdn.microsoft.com/en-us/magazine/cc164193.aspx),它附帶了一個工具,可以讓你的生活更輕鬆。 – dasblinkenlight 2012-04-17 10:43:15

+0

@dasblinkenlight感謝您的建議。不幸的是它沒有幫助,但我更新了這個問題。 – PVitt 2012-04-17 10:54:31

+1

您是否嘗試在'DllImport'屬性中指定'CallingConvention = CallingConvention.Cdecl'? – svick 2012-04-17 11:04:15

回答

3

你需要一個引用傳遞的指針或「雙指針」一樣,

__declspec(dllexport) int WaitForData(unsigned char** pBuffer) 

,然後改變指針的值

*pBuffer = 'something' 
(因爲它是由 通過)

其他選項 - 返回指針(然後你必須以其他方式處理整數/長度)

btw這就是爲什麼你自動生成的原型看起來像這樣(沒有out,ref修飾符)

+0

然後'__declspec(dllexport)int WaitForData(無符號字符* pBuffer)'和'公共靜態extern int WaitForData(字節緩衝區);'更好? – PVitt 2012-04-17 11:14:53

+1

nope - 如果您不想改變指針的值(這是數字地址),您需要更改上面顯示的本地方法的簽名(或者如果您更喜歡那樣,則使用unsigned char *&pBuffer)這樣做你可以使用它,但不能將它從方法中改變 - 這就是c/C++實現out/ref參數的方式 – Bond 2012-04-17 11:22:17

+0

是的,它是雙指針。 – PVitt 2012-04-17 11:30:44