use*_*150 10 c c# string pinvoke dllimport
C DLL中的函数如下所示:
int my_Funct(char* input, char* output);
Run Code Online (Sandbox Code Playgroud)
我必须从C#app调用它.我通过以下方式执行此操作:
...DllImport stuff...
public static extern int my_Funct(string input, string output);
Run Code Online (Sandbox Code Playgroud)
输入字符串完美地传输到DLL(我有可见的证明).函数填写的输出虽然错误.我有六进制数据,如:
3F-D9-00-01
Run Code Online (Sandbox Code Playgroud)
但不幸的是,切断两个零之后的所有内容,只有前两个字节来到我的C#应用程序.它发生了,因为(我猜)它将它视为空字符并将其作为字符串的结尾.
任何想法我怎么能摆脱它?我试图将它指定为IntPtr而不是字符串,但我不知道以后如何处理它.我尝试过后:
byte[] b1 = new byte[2];
Marshal.Copy(output,b1,0,2);
Run Code Online (Sandbox Code Playgroud)
2通常应该是字节数组的长度.但我得到了各种错误:例如"请求的范围超出了数组的末尾".或"试图读取或写入受保护的内存......"
我感谢任何帮助.
Dav*_*nan 14
您错误地编组输出字符串.使用string在p /调用从托管到本机传递数据时声明是合适的.但是,当数据向另一个方向流动时,您无法使用它.相反,你需要使用StringBuilder.像这样:
[DllImport(...)]
public static extern int my_Funct(string input, StringBuilder output);
Run Code Online (Sandbox Code Playgroud)
然后为输出分配内存:
StringBuilder output = new StringBuilder(256);
//256 is the capacity in characters - only you know how large a buffer is needed
Run Code Online (Sandbox Code Playgroud)
然后你可以调用该函数.
int retval = my_Funct(inputStr, output);
string outputStr = output.ToString();
Run Code Online (Sandbox Code Playgroud)
另一方面,如果这些参数中包含空字符,则无法编组为字符串.那是因为编组人员不会在null之后编组任何东西.相反,您需要将其编组为字节数组.
public static extern int my_Funct(
[In] byte[] input,
[Out] byte[] output
);
Run Code Online (Sandbox Code Playgroud)
这符合你的C声明.
然后假设ANSI编码将输入字符串转换为字节数组,如下所示:
byte[] input = Encoding.Default.GetBytes(inputString);
Run Code Online (Sandbox Code Playgroud)
如果您想使用不同的编码,很明显该怎么做.
对于输出,您需要分配数组.假设它与输入的长度相同,你会这样做:
byte[] output = new byte[input.Length];
Run Code Online (Sandbox Code Playgroud)
不知何故,你的C函数必须知道数组的长度.我会留给你的!
然后你可以调用该函数
int retval = my_Funct(input, output);
Run Code Online (Sandbox Code Playgroud)
然后将输出数组转换回C#字符串,Encoding再次使用该类.
string outputString = Encoding.Default.GetString(output);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4694 次 |
| 最近记录: |