如何使用DLLImport为C#封送带有字节*字段的C结构
我试图弄清楚如何正确封送包含字节*字段的C结构,以便可以从C#应用程序向第三方API发送命令。但是,我不断收到关于参数的错误。这是我从C代码得到的:如何使用DLLImport为C#封送带有字节*字段的C结构,c#,.net,marshalling,C#,.net,Marshalling,我试图弄清楚如何正确封送包含字节*字段的C结构,以便可以从C#应用程序向第三方API发送命令。但是,我不断收到关于参数的错误。这是我从C代码得到的: struct MY_STRUCT { int32 Object; // Object index, dependent of the context int32 Cmd; // Command code byte *Params; // pointer
struct MY_STRUCT
{
int32 Object; // Object index, dependent of the context
int32 Cmd; // Command code
byte *Params; // pointer to parameters
};
int32 stdcall SendCommand( int32 DeviceId, MY_STRUCT *Cmd );
这就是我目前在C代码中引用它的方式:
猜猜看?当发送诸如Byte、Int32等基本类型时,它工作得非常好…最可能的问题是您混淆了字节和字符。特别是,您有:
byte[] bytes = new byte[parametros.Length * sizeof(char)];
System.Buffer.BlockCopy(parametros.ToCharArray(), 0, bytes, 0, bytes.Length);
IntPtr p = Marshal.AllocHGlobal(bytes.Length);
这基本上是正确的,因为您考虑到char
的长度是两个字节。但是你有:
Marshal.Copy(bytes, 0, p, parametros.Length);
这是一个问题,因为您只复制parametros.Length
bytes,它正好是bytes
数组长度的一半
我想你想把它改成字节.Length
我看到的另一个问题是,您没有提供任何说明字节序列长度的内容(即nocbParams
value,或类似内容),如果它被视为字符串,则没有空终止符
而且,正如Hans Passant指出的,无论如何,C代码不太可能理解一堆2字节的“字符”。他建议使用
Marshal.StringToHGlobalAnsi
可能是正确的。最可能的问题是您混淆了字节和字符。特别是,您有:
byte[] bytes = new byte[parametros.Length * sizeof(char)];
System.Buffer.BlockCopy(parametros.ToCharArray(), 0, bytes, 0, bytes.Length);
IntPtr p = Marshal.AllocHGlobal(bytes.Length);
这基本上是正确的,因为您考虑到char
的长度是两个字节。但是你有:
Marshal.Copy(bytes, 0, p, parametros.Length);
这是一个问题,因为您只复制parametros.Length
bytes,它正好是bytes
数组长度的一半
我想你想把它改成字节.Length
我看到的另一个问题是,您没有提供任何说明字节序列长度的内容(即nocbParams
value,或类似内容),如果它被视为字符串,则没有空终止符
而且,正如Hans Passant指出的,无论如何,C代码不太可能理解一堆2字节的“字符”。他建议使用
Marshal.StringToHGlobalAnsi
可能是正确的。最可能的问题是您混淆了字节和字符。特别是,您有:
byte[] bytes = new byte[parametros.Length * sizeof(char)];
System.Buffer.BlockCopy(parametros.ToCharArray(), 0, bytes, 0, bytes.Length);
IntPtr p = Marshal.AllocHGlobal(bytes.Length);
这基本上是正确的,因为您考虑到char
的长度是两个字节。但是你有:
Marshal.Copy(bytes, 0, p, parametros.Length);
这是一个问题,因为您只复制parametros.Length
bytes,它正好是bytes
数组长度的一半
我想你想把它改成字节.Length
我看到的另一个问题是,您没有提供任何说明字节序列长度的内容(即nocbParams
value,或类似内容),如果它被视为字符串,则没有空终止符
而且,正如Hans Passant指出的,无论如何,C代码不太可能理解一堆2字节的“字符”。他建议使用
Marshal.StringToHGlobalAnsi
可能是正确的。最可能的问题是您混淆了字节和字符。特别是,您有:
byte[] bytes = new byte[parametros.Length * sizeof(char)];
System.Buffer.BlockCopy(parametros.ToCharArray(), 0, bytes, 0, bytes.Length);
IntPtr p = Marshal.AllocHGlobal(bytes.Length);
这基本上是正确的,因为您考虑到char
的长度是两个字节。但是你有:
Marshal.Copy(bytes, 0, p, parametros.Length);
这是一个问题,因为您只复制parametros.Length
bytes,它正好是bytes
数组长度的一半
我想你想把它改成字节.Length
我看到的另一个问题是,您没有提供任何说明字节序列长度的内容(即nocbParams
value,或类似内容),如果它被视为字符串,则没有空终止符
而且,正如Hans Passant指出的,无论如何,C代码不太可能理解一堆2字节的“字符”。他建议使用
Marshal.StringToHGlobalAnsi
可能是正确的。这段MSDN代码可能会让你知道如何使用:C代码以你现在的方式理解字符串的可能性非常小。使用Marshal.StringToHGlobalAnsi()。否则,这只是没有规范的胡乱猜测。您能分享错误消息或错误代码吗?@Sjips不幸的是,错误代码是特定于API的,不能说明问题。它被翻译成“无效参数”…@HansPassant我想我会为此投入一些资金。。。我要试试这个。谢谢你的提示。这段MSDN代码可能会给你一个想法:C代码理解字符串的可能性与你现在所做的差不多。使用Marshal.StringToHGlobalAnsi()。否则,这只是没有规范的胡乱猜测。您能分享错误消息或错误代码吗?@Sjips不幸的是,错误代码是特定于API的,不能说明问题。它被翻译成“无效参数”…@HansPassant我想我会为此投入一些资金。。。我要试试这个。谢谢你的提示。这段MSDN代码可能会给你一个想法:C代码理解字符串的可能性与你现在所做的差不多。使用Marshal.StringToHGlobalAnsi()。否则,这只是没有规范的胡乱猜测。您能分享错误消息或错误代码吗?@Sjips不幸的是,错误代码是特定于API的,不能说明问题。它被翻译成“无效参数”…@HansPassant我想我会为此投入一些资金。。。我要试试这个。谢谢你的提示。这段MSDN代码可能会给你一个想法:C代码理解字符串的可能性与你现在所做的差不多。使用Marshal.StringToHGlobalAnsi()。否则,这只是没有规范的胡乱猜测。您能分享错误消息或错误代码吗?@Sjips不幸的是,错误代码是API规范