2016-04-26 58 views
0

我有以下的C函數,我需要從C#調用:我已經聲明在C#側以下獲取字節數組由C到C#

__declspec(dllexport) int receive_message(char* ret_buf, int buffer_size); 

[DllImport("MyCLibrary", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto, EntryPoint = "receive_message")] 
public static extern int ReceiveMessage([MarshalAs(UnmanagedType.LPStr)]StringBuilder retBuf, int bufferSize); 

我是這樣調用函數:

StringBuilder sb = new StringBuilder(); 
int len = ReceiveMessage(sb, 512); 

這對我最初的測試,我收到「字符串」消息時正常工作。但是,現在我想接收打包的消息(字符/字節數組)。問題是字符/字節數組將會有0,並且會終止字符串,所以我不回覆整個消息。任何想法如何我可以重構獲得字節數組?

+0

使用Marshal.Copy(IntPtr source,byte [] destination,int startIndex,int length)。 – jdweng

+0

@jdweng,我沒跟着。我需要在我的C#中更改我的extern聲明嗎? – bsh152s

+0

你對* bufferSize *參數進行了細化,該StringBuilder的容量爲0.這可能會導致堆損壞,這可能會非常不愉快。如果它實際上不是一個字符串,那麼你必須將第一個參數聲明爲byte []。同樣的事情,傳遞它的Length屬性作爲第二個參數。 –

回答

1

隨着jdweng的幫助下,我已經改變了聲明:

[DllImport("MyCLibrary", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto, EntryPoint = "receive_message")] 
public static extern int ReceiveMessage(IntPtr retBuf, int bufferSize); 

而且,我分配和編組與數據一起釋放在C#側的內存。

IntPtr pnt = Marshall.AllocHGlobal(512); 
try 
{ 
    int len = ReceiveMessage(pnt, 512); 
    ... 
    byte[] bytes = new byte[len]; 
    Marshal.Copy(pnt, bytes, 0, len); 
    ... 
} 
finally 
{ 
    Marshal.FreeHGlobal(pnt); 
}