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;namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        //结构体转byte数组
        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;
        }        //byte数组转结构体
        public static object BytesToStruct(byte[] bytes, Type type)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(type);
            //byte数组长度小于结构体的大小
            if (size > bytes.Length)
            {
                //返回空
                return null;
            }
            //分配结构体大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将byte数组拷到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换为目标结构体
            object obj = Marshal.PtrToStructure(structPtr, type);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回结构体
            return obj;
        }
        public Form1()
        {
            InitializeComponent();
        }        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        struct TESTStruct
        {
            public byte length;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
            public string number;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            TESTStruct test = new TESTStruct();
            test.number = "012345";
            test.length = (byte)test.number.Length;
            byte[] testBytes = StructToBytes(test);
            TESTStruct objTest = new TESTStruct();
            objTest = (TESTStruct)BytesToStruct(testBytes, typeof(TESTStruct));
            MessageBox.Show(objTest.number);
            MessageBox.Show(objTest.length.ToString());
        }
    }
}
上面的这段程序执行结果number显示不全,少了一位,只显示01234,找了半天不知道是啥原因,请各位帮忙,多谢多谢

解决方案 »

  1.   

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
                public string number;===》
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
                public string number;
      

  2.   

    把SizeConst改为7可以显示全,但是这个是与其它语言写的程序通信用的,结构体大小有限制,要求这个结构体第一个字段表示有效长度,第二个字段是一个6字节的字符串,总共7个字节不能变
      

  3.   

    所有的哲人都是有逻辑的
    没有逻辑的人是混乱的既然不能用string 封送,为何不用byte[] 呢?
      

  4.   

       object obj = Marshal.PtrToStructure(structPtr, type);
    应该是这里从非托管对象到托管对象出了问题,非托管的字符串必须结尾有\0,而你长度是定长了,所以最后一位进入非托管环境充当了结束符,进入托管环境之后还原没了。