C#学习笔记——CopyMemory
Socket接收到的byte []要转换成自定义的struct / 自定义Struct转换成byte []都相当麻烦
用循环去转换太浪费时间了……于是想到用CopyMemory,Google一圈终于搞定
下面的代码是在Snippet Compiler里编译通过的
C#代码
#region Imports
using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Text;
using System.Data;
using System.Drawing;
using System.Threading;
using System.Reflection;
using System.Collections;
using System.Net.Sockets;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Imaging;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
#endregion
#region Assembly Info
[assembly: AssemblyTitle("Test Application by eglic")]
[assembly: AssemblyDescription("Test Application by eglic")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("eGlic.Com")]
[assembly: AssemblyProduct("Test Application by eglic")]
[assembly: AssemblyCopyright("Copyright (C) eGlic.Com 2007")]
[assembly: AssemblyTrademark("eGlic.Com")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
#endregion
namespace eGlic
{
#region Application Entrance
public class Test{
[STAThread]
public static void Main() {
byte [] buffer=new byte [20];
DataGraphHeader header=new DataGraphHeader();
string data="ABCDEFGH";
header.Signature=0xFF;
header.Protocol.Type=1;
header.Protocol.Version=1;
header.Type=99;
header.SerialID=1234567;
header.Size=8;
Win32API.CopyMemoryEx(buffer,ref header);
Win32API.CopyMemoryEx(buffer,12,System.Text.Encoding.ASCII.GetBytes(data),0,8);
string o="";
for(int i=0;i<buffer.Length;i++){
if(buffer[i]<10) o+="0";
o+=String.Format("{0:X}",buffer[i]);
o+=" ";
}
MessageBox.Show(o,"转成Byte []之后的数据包",MessageBoxButtons.OK,MessageBoxIcon.Information);
DataGraphHeader h=new DataGraphHeader();
byte [] buf;
string d="";
Win32API.CopyMemoryEx(ref h,buffer);
buf=new byte [h.Size];
Win32API.CopyMemoryEx(buf,buffer,12,h.Size);
o="h.Signature=" +h.Signature.ToString()+"/r/n";
o+="h.Protocol.Type=" +h.Protocol.Type.ToString()+"/r/n";
o+="h.Protocol.Version=" +h.Protocol.Version.ToString()+"/r/n";
o+="h.Type=" +h.Type.ToString()+"/r/n";
o+="h.SerialID=" +h.SerialID.ToString()+"/r/n";
o+="h.Size=" +h.Size.ToString()+"/r/n";
o+="附加数据为:"+System.Text.Encoding.ASCII.GetString(buf);
MessageBox.Show(o,"解析后数据包",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
}
#endregion
#region Win32API
public class Win32API {
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", CharSet = CharSet.Ansi)]
public extern static long CopyMemory(IntPtr dest, IntPtr source, int size);
#region CopyMemoryEx
/// <summary>
/// CopyMemoryEx
/// </summary>
/// <param name="dest">目标缓存区</param>
/// <param name="source">DataGraphPackage</param>
/// <returns></returns>
public unsafe static long CopyMemoryEx(byte[] dest, ref DataGraphHeader source) {
return CopyMemoryEx(dest, 0,ref source);
}
/// <summary>
/// CopyMemoryEx
/// </summary>
/// <param name="dest">目标缓存区</param>
/// <param name="DestStart">目标缓存区中的开始位置</param>
/// <param name="source">DataGraphPackage</param>
/// <returns></returns>
public unsafe static long CopyMemoryEx(byte[] dest,int DestStart, ref DataGraphHeader source) {
IntPtr dp;
IntPtr sp;
fixed (byte* ds = &dest[DestStart]) {
fixed (DataGraphHeader* sr = &source) {
dp = (IntPtr)ds;
sp = (IntPtr)sr;
return CopyMemory(dp, sp, sizeof(DataGraphHeader));
}
}
}
/// <summary>
/// CopyMemoryEx
/// </summary>
/// <param name="dest">DataGraphPackage</param>
/// <param name="source">源数据缓存</param>
/// <returns></returns>
public unsafe static long CopyMemoryEx(ref DataGraphHeader dest, byte[] source) {
return CopyMemoryEx(ref dest, source, 0);
}
/// <summary>
/// CopyMemoryEx
/// </summary>
/// <param name="dest">DataGraphPackage</param>
/// <param name="source">源数据缓存</param>
/// <returns></returns>
public unsafe static long CopyMemoryEx(ref DataGraphHeader dest, byte[] source,int SourceStart) {
IntPtr dp;
IntPtr sp;
fixed (DataGraphHeader* ds = &dest) {
fixed (byte* sr = &source[SourceStart]) {
dp = (IntPtr)ds;
sp = (IntPtr)sr;
return CopyMemory(dp, sp, sizeof(DataGraphHeader));
}
}
}
/// <summary>
/// CopyMemoryEx
/// </summary>
/// <param name="dest">目标缓存</param>
/// <param name="source">源数据</param>
/// <param name="size">要从源数据中复制的长度</param>
/// <returns></returns>
public unsafe static long CopyMemoryEx(byte[] dest, byte[] source, int size) {
return CopyMemoryEx(dest, 0, source, 0, size);
}
/// <summary>
/// CopyMemoryEx
/// </summary>
/// <param name="dest">目标缓存</param>
/// <param name="source">源数据</param>
/// <param name="SourceStart">源数据缓存中开始位置</param>
/// <param name="size">要从源数据中复制的长度</param>
/// <returns></returns>
public unsafe static long CopyMemoryEx(byte[] dest, byte[] source, int SourceStart,int size) {
return CopyMemoryEx(dest, 0, source, SourceStart, size);
}
/// <summary>
/// CopyMemoryEx
/// </summary>
/// <param name="dest">目标缓存</param>
/// <param name="DestStart">目标缓存中开始复制的位置</param>
/// <param name="source">源数据</param>
/// <param name="SourceStart">源数据缓存中开始位置</param>
/// <param name="size">要从源数据中复制的长度</param>
/// <returns></returns>
public unsafe static long CopyMemoryEx(byte[] dest,int DestStart, byte[] source, int SourceStart, int size) {
IntPtr dp;
IntPtr sp;
fixed (byte* ds = &dest[DestStart]) {
fixed (byte* sr = &source[SourceStart]) {
dp = (IntPtr)ds;
sp = (IntPtr)sr;
return CopyMemory(dp, sp, size);
}
}
}
#endregion
}
#endregion
[StructLayout(LayoutKind.Sequential)]
public struct ProtocolInfo {
public byte Type;
public byte Version;
}
[StructLayout(LayoutKind.Sequential)]
public struct DataGraphHeader {
public byte Signature; //包头: 1字节
public ProtocolInfo Protocol; //协议: 2字节
public byte Type; //包类型: 1字节
public uint SerialID; //包序号 4字节
public int Size; //包尺寸 4字节
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Python/archive/2007/08/24/1757002.aspx