C DLL中的PInvoke char *在C#中作为String处理。 null字符问题

C DLL中的函数如下所示:

int my_Funct(char* input, char* output); 

我必须从C#app调用它。 我这样做的方式如下:

 ...DllImport stuff... public static extern int my_Funct(string input, string output); 

输入字符串完美地传输到DLL(我有可见的certificate)。 function填写的输出虽然是错误的。 我有六进制数据,如:

 3F-D9-00-01 

但不幸的是,在两个零之后的所有内容都被剪切掉了,只有前两个字节来到我的C#应用​​程序。 它发生了,因为(我猜)它将它视为空字符并将其作为字符串的结尾。

任何想法我怎么能摆脱它? 我试图将它指定为IntPtr而不是字符串,但我不知道以后如何处理它。 我尝试过后:

  byte[] b1 = new byte[2]; Marshal.Copy(output,b1,0,2); 

2通常应该是字节数组的长度。 但是我得到了各种错误:比如“请求的范围超出了数组的末尾”。 或“试图读取或写入受保护的内存……”

我感谢任何帮助。

您错误地编组输出字符串。 在将数据从托管传递到本机时,在p / invoke声明中使用string是合适的。 但是,当数据向另一个方向流动时,您无法使用它。 相反,您需要使用StringBuilder 。 像这样:

 [DllImport(...)] public static extern int my_Funct(string input, StringBuilder output); 

然后为输出分配内存:

 StringBuilder output = new StringBuilder(256); //256 is the capacity in characters - only you know how large a buffer is needed 

然后你可以调用该函数。

 int retval = my_Funct(inputStr, output); string outputStr = output.ToString(); 

另一方面,如果这些参数中包含空字符,那么您就不能编组为字符串。 这是因为编组人员不会编组超过null的任何东西。 相反,您需要将其编组为字节数组。

 public static extern int my_Funct( [In] byte[] input, [Out] byte[] output ); 

这符合你的C声明。

然后假设ANSI编码将输入字符串转换为字节数组,如下所示:

 byte[] input = Encoding.Default.GetBytes(inputString); 

如果你想使用不同的编码,很明显该怎么做。

对于输出,您需要分配数组。 假设它与输入的长度相同,你会这样做:

 byte[] output = new byte[input.Length]; 

不知何故,你的C函数必须知道数组的长度。 我会留给你的!

然后你可以调用该函数

 int retval = my_Funct(input, output); 

然后将输出数组转换回C#字符串,再次使用Encoding类。

 string outputString = Encoding.Default.GetString(output);