C#如何发结构体数组,另integer对应C#哪个数据类型

shuihan20e 2013-06-27 12:54:23
软件的客户端原来是用DELPHI写的,翻译成C#,服务器端是VC写的,原来的协议比较复杂,我就用DELPHI写了一个非常简单的

现在卡在了C#发送结构体,结构体中字符串与BYTE类型的都没有问题,但是发送整数据(delphi中integer,C#中int或Int32)收到的数据是错误的

另外如果结构体中有结构体数组时,应该如何写,如何给结构体的数据赋值呢?
上代码

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text;using System.Windows.Forms; using System.Runtime.InteropServices; using MTWS.Net.SocketClient;  namespace MTWS.Net.AppCode {     public partial class TestTcp : Form     {         public TestTcp()         {             InitializeComponent();         }          struct TMsgHeadInfo         {             //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]             public char MsgCode;             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]             public char[] MsgType;             public byte Sender;             //public int SendInt;         }          struct TMsgBody         {             public TMsgHeadInfo msghead;   //假如这里是一个结构体数组时应该如何定义和赋值呢?       //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]             //public TMsgHeadInfo[] msghead;  这样是不对的       //public TMsgHeadInfo[2] msghead; 这样也不对      //此处到底应该怎样定义与赋值?另外,协议是原来定好了的,肯定不能变了,改协议来解决这个问题的话,就不用提了      public Int32 body;   //这里哪个类型对就DELPHI里的integer?         }          public static byte[] StructToBytes(object structObj)         {             //得到结构体的大小      int size = Marshal.SizeOf(structObj);           //创建byte数组             byte[] bytes = new byte[size];           //分配结构体大小的内存空间             IntPtr structPtr = Marshal.AllocHGlobal(size);            //将结构体拷到分配好的内存空间              Marshal.StructureToPtr(structObj, structPtr, false);             //从内存空间拷到byte数组            Marshal.Copy(structPtr, bytes, 0, size);             //释放内存空间             Marshal.FreeHGlobal(structPtr);             //返回byte数组            return bytes;         }         private void TestTcp_Load(object sender, EventArgs e)         {                    }          private void button1_Click(object sender, EventArgs e)         {             int ret;            TMsgBody msgbody;             //TMsgHeadInfo msghead;             TCPClient tcp = new TCPClient();             string code = "zp";             string type = "ai";             //string body = "cc";             ret = tcp.ConnectServer("127.0.0.1", 3578);             if (ret == 0)             {                 MessageBox.Show("连接服务器失败");                          }             else            {                 MessageBox.Show("连接服务器成功");                 msgbody.msghead.MsgCode = code.ToCharArray();                  msgbody.msghead.MsgType = type.ToCharArray();                  msgbody.msghead.Sender = 5;                  msgbody.body = 44;//    服务器端收到后,实际不是44,其他数据类型没有问题          byte[] msg = StructToBytes(msgbody);                 if (tcp.SendMsg(msg) > 0)                 {                     MessageBox.Show("发送成功");                 }                 else                {                    MessageBox.Show("发送失败");                 }             }          }     } } 


服务器端delphi代码,组件用的indy9
 unit Unit1;   interface  uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPServer;   type  TChar2 = array[0..1] of Char;   TMsgHead=packed record    MsgCode, MsgType: TChar2;     sender: Byte;     senderint: Integer;   end;     TMsgBody=packed record    msgHead: TMsgHead;     body: Integer;   end;     TForm1 = class(TForm)     IdTCPServer1: TIdTCPServer;     Button1: TButton;     Edit1: TEdit;     Edit2: TEdit;     Edit3: TEdit;     Edit4: TEdit;     procedure Button1Click(Sender: TObject);     procedure IdTCPServer1Execute(AThread: TIdPeerThread);   private    { Private declarations }  public    { Public declarations }  end;   var  Form1: TForm1;   implementation  {$R *.dfm}   procedure TForm1.Button1Click(Sender: TObject); begin  IdTCPServer1.DefaultPort := 3578;   IdTCPServer1.Active := True; end;   function Min(AValueOne, AValueTwo : Integer): Integer; begin  If AValueOne > AValueTwo then  begin    Result := AValueTwo   end //If AValueOne > AValueTwo then   else  begin    Result := AValueOne;   end; //..If AValueOne > AValueTwo then end;   function PCharToStr(ABuf: array of char; ABufLen: Integer): string; {   将PChar(#0结尾)转换为string }var  LenOfStr: Integer; begin  LenOfStr := Min(ABufLen, StrLen(ABuf));   if LenOfStr <= 0 then  begin    Result := '';   end  else  begin    SetLength(Result, LenOfStr);     Move(ABuf[0], Result[1], LenOfStr);   end; end;   procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); //var msgHead: TMsgHead; var msgBody: TMsgBody; begin    if AThread.Connection.Connected then begin      FillChar(msgBody, SizeOf(TMsgBody), 0);       AThread.Connection.ReadBuffer(msgBody, SizeOf(TMsgBody));       Edit1.Text := PCharToStr(msgBody.msgHead.MsgCode, 2);       Edit2.Text := PCharToStr(msgBody.msgHead.MsgType, 2);       Edit3.Text := IntToStr(Integer(msgBody.msgHead.sender));       Edit4.Text := IntToStr(msgBody.msgHead.senderint);     end; end;   end. 
...全文
306 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
shuihan20e 2013-07-03
  • 打赏
  • 举报
回复
问题已解决,加上[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]就可以,谢谢楼上各位
shuihan20e 2013-06-27
  • 打赏
  • 举报
回复
shuihan20e 2013-06-27
  • 打赏
  • 举报
回复
引用 3 楼 sololie 的回复:
一行代码几公里长,没法看了
见二楼的地址
sololie 2013-06-27
  • 打赏
  • 举报
回复
一行代码几公里长,没法看了
sololie 2013-06-27
  • 打赏
  • 举报
回复
integer是32位有符号整数,对应c#的 int和int32

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧