如何使用DLLImport为C#封送带有字节*字段的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

我试图弄清楚如何正确封送包含字节*字段的C结构,以便可以从C#应用程序向第三方API发送命令。但是,我不断收到关于参数的错误。这是我从C代码得到的:

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

我看到的另一个问题是,您没有提供任何说明字节序列长度的内容(即no
cbParams
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

我看到的另一个问题是,您没有提供任何说明字节序列长度的内容(即no
cbParams
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

我看到的另一个问题是,您没有提供任何说明字节序列长度的内容(即no
cbParams
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

我看到的另一个问题是,您没有提供任何说明字节序列长度的内容(即no
cbParams
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规范