2016-04-26 57 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); 
}