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,找了半天不知道是啥原因,请各位帮忙,多谢多谢
public string number;===》
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
public string number;
没有逻辑的人是混乱的既然不能用string 封送,为何不用byte[] 呢?
应该是这里从非托管对象到托管对象出了问题,非托管的字符串必须结尾有\0,而你长度是定长了,所以最后一位进入非托管环境充当了结束符,进入托管环境之后还原没了。