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字节
- }
- }