2014-10-29 43 views
0

我想了解如何正確地編組包含字節*的字段的C結構,以便可以將命令從C#應用程序發送到第三方API 。但是,我不斷收到抱怨參數的錯誤。這是我從C代碼:如何使用DLLImport爲C#編譯帶有字節*的字段的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#代碼:

public struct MY_STRUCT 
{ 
    public Int32 Object;   // Object index, dependent of the context 
    public Int32 Cmd;    // Command code 
    public IntPtr Params;   // pointer to parameters 
}; 

[DllImport("C:\\Client.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern Int32 SendCommand(Int32 DeviceId, ref MY_STRUCT Cmd); 

Int32 CSharpSendCommand(int placa, int chan, int code, String parametros) 
    { 
     MY_STRUCT cmd = new MY_STRUCT(); 
     cmd.Cmd = code; 
     cmd.Object = chan; 
     byte[] bytes = new byte[parametros.Length * sizeof(char)]; 
     System.Buffer.BlockCopy(parametros.ToCharArray(), 0, bytes, 0, bytes.Length); 
     IntPtr p = Marshal.AllocHGlobal(bytes.Length); 
     try { 
      Marshal.Copy(bytes, 0, p, parametros.Length); 
      cmd.Params = p; 
      Int32 ret = Translated.SendCommand(placa, ref cmd); 
      if (ret != (int)LibraryStatus.Success) 
       Console.Out.Write("Erro: Comando 0x{0} retornou: {1}\n", code, ret); 

      return ret; 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(p); 
     } 
    } 

任何的猜測?在發送諸如Byte,Int32之類的原始類型時,它非常好用,等等......

+0

此MSDN代碼可能會給你一個想法如何:http://msdn.microsoft.com/en-us/library/0szztey7.aspx – 2014-10-29 21:04:44

+2

C代碼將理解字符串的可能性是你現在正在做的事情是關於zilch。使用Marshal.StringToHGlobalAnsi()。否則這只是瘋狂猜測沒有規範。 – 2014-10-29 21:22:17

+1

你能分享錯誤信息或錯誤代碼嗎? – Sjips 2014-10-29 21:24:45

回答

3

最有可能的問題是你混淆了字節和字符。特別是,你有這樣的:

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

我看到的另一個問題是,你沒有提供任何說明該字節序列有多長(即沒有0​​值或類似的值),並且如果應該像字符串那樣對待沒有空終止符。

而且,正如Hans Passant指出的那樣,C代碼不太可能理解一堆2字節的「字符」。他建議使用Marshal.StringToHGlobalAnsi可能是對的。

+0

非常感謝您的意見。 Marshal.StringToHGlobalAnsi做了詭計! – 2014-10-29 22:56:37