本人刚学这方面的dd。大概需要实现这样的程序:VC6和C#之间需要用socket通信,互相发些报文,格式都是用结构体定义的,看了些资料,说是要用到下面的两个方法
 static object BytesToStruct(byte[] bytes, Type strcutType)
        {
            int size = Marshal.SizeOf(strcutType);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        } static byte[] StructToBytes(object structObj)
        {
            int size = Marshal.SizeOf(structObj);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structObj, buffer, false);
                byte[] bytes = new byte[size];
                Marshal.Copy(buffer, bytes, 0, size);
                return bytes;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }        }
现在还有几个疑问,想问下大虾们
1 C#发给VC的报文,struct是不是不用StructToBytes转成byte,直接用System.Text.Encoding.BigEndianUnicode.GetBytes就可以了??
2 VC发过来的报文是需要用BytesToStruct吧byte转成struct吗?
3 发送和接受 有什么方法send和read之类的吗?NetworkStream????总之脑子有点乱,帮忙给缕缕,思路代码统统欢迎!!分不多了呵呵,望见谅!

解决方案 »

  1.   

    直接用System.Text.Encoding.BigEndianUnicode.GetBytes是否可以, 不清楚1,2都转换是可以正常收到报文的3 Socket类就有相应Send和Receive方法
      

  2.   

    现在用StructToBytes和BytesToStruct方法已经把结构体传过来了,想用richbox直接把接收到得结构体显示出来,现在用richTextBox1.AppendText(struct.结构体成员1+"\r\n"+struct.结构体成员2+"\r\n"+........+"\r\n")有其他方法没??这样要是结构体很多成员的话,很郁闷!
      

  3.   

    还有一个问题结构体初始化放在哪里呢?
    开始是放在这里的:
    public struct struct1
            {
                public uint dwSourceIP; //服务器端ip           
                public uint dwDestinationIP; //客户端ip 
                public struct1(int i) // 初始化
                {
                    this.dwSourceIP = 0xDA02030A;
                    this.dwDestinationIP = 0xDA020301;            
                }            
            }
    这样好像没有把数据传过来,后来就放在StructToBytes前面了。
    上面红字的地方其实int i是没有用到的,我的这个结构体里面只是uint的,只是提示错误 1 结构不能包含显式的无参数构造函数,才加上的。
    还有就是十六进制的数据0xDA02030A 传过来变成十进制的了。。
      

  4.   

    struct不能有显示的无参构造函数,这是规定
    不论十进制还是十六进制,都是你看到的表象。
      

  5.   

    谢谢回答!richTextBox显示的问题谁告诉一下哈
      

  6.   


    使用反射,这样:(假设你的结构体叫struct1)            foreach (FieldInfo pi in struct1.GetType().GetFields())
                {
                    richTextBox1.AppendText(pi.Name + ":" + pi.GetValue(struct1) + "\r\n");
                }
      

  7.   

    1 C#发给VC的报文,struct是不是不用StructToBytes转成byte,直接用System.Text.Encoding.BigEndianUnicode.GetBytes就可以了??
    ====>
    当然不行。
    socket发送c++中的struct,其实是对struct对象所在的一段内存数据发过来。
    而System.Text.Encoding.BigEndianUnicode.GetBytes是将字符串转化为二进制流。
    2 VC发过来的报文是需要用BytesToStruct吧byte转成struct吗?
    对。
    也可以对发过来的数据进行解析,然后new一个C#中的struct对象。
    如:
    vc中的struct定义如下:
    // 假设内存边界对齐为1
    struct cpp_struct{
       int x;
       int y;
    };
    用socket发送cpp_struct的对象,C#接收到之后,解析前4个字节为x, 后4个字节为y,然后根据x, y,new一个csharp_struct出来。3 发送和接受 有什么方法send和read之类的吗?NetworkStream???? 
    System.Net.Sockets命名空间下有很多有用的类可以用。如:Socket, NetworkStream, TcpClient或者TcpListener。vc的话,当然是用winsock啦.
      

  8.   

    接收到的结构体中,重写ToString方法,然后richTextBox1.Text = struct.ToString();就可以了。
      

  9.   

    实际上,用unsafe代码比较方便。把结构直接转为byte[]发送,把接收到的byte[]直接转为结构,不用mashal那样分配和复制内存。
      

  10.   

    To:soaringbird
    下面是刚才csdn里搜的
    你说的用unsafe代码是这个意思吗?
    ————————————————————————
    如下定义结构:  
      [StructLayout(LayoutKind.Sequential,   Pack=1)]  
      public   struct   pack_LogOn  
      {  
      byte   byFlag;  
      byte   bySystemID;  
      byte   byFlagType;  
      byte   byReserve;  
      ushort   uSize;  
      byte   byDataID;  
      ushort   uBureauID;  
      ushort   uFCS;  
       
      public   unsafe   byte[]   GetBytes()  
      {  
      byte[]   arr   =   new   byte[   sizeof(pack_LogOn)   ];  
      fixed(   byte*   parr   =   arr   )  
      {   *((pack_LogOn*)parr)   =   this;   }  
      return   arr;  
      }  
      }  
      请注意StructLayout的用法和public   unsafe   byte[]   GetBytes()  
       
      数据发送代码如下:  
      pack_LogOn   pack=new   pack_LogOn;  
      //填入数据  
      Byte[]   sendBytes   =   pack.GetBytes();  
      socket.Send(sendBytes,   sendBytes.Length,   SocketFlags.None);   
      

  11.   

    对,大概是这样的吧。这段代码是把结构转为byte[],其中那句byte[]  arr  =  new  byte[  sizeof(pack_LogOn)  ];  后面那个new应该是不必要的。
    把byte[]转为结构是这样的,以上面那个结构为例:
    pack_LogOn pack;
    fixed(byte* pbuf=buf)
    {
    pack=*(pack_LogOn)pbuf;
    }
    除了那些unsafe相关的语句,跟C++里基本一样