C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比
生活随笔
收集整理的這篇文章主要介紹了
C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C#調用C++ memcpy實現各種參數類型的內存拷貝 VS marshal.copy的實現 效率對比
using System; using System.Runtime.InteropServices; using System.IO; namespace tx {struct ST{public char c1;public int x;public int y;}class Ct{[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]public static extern void MemCopy(byte[] dest, byte[] src, int count);//字節數組到字節數組的拷貝 [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]public static extern void MemCopy(int[] dest, byte[] src, int count);//字節數組到整形數組的拷貝 [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]public unsafe static extern void MemCopy(ref ST dest, byte[] src, int count);//注意只有結構體能這么做,class不可以static void Main(string[] args){//測試----------------------------------------------var ms = new MemoryStream();BinaryWriter writer = new BinaryWriter(ms);writer.Write((byte)'a');writer.Write((byte)'b');writer.Write((byte)'c');writer.Write((byte)'d');writer.Write((Int32)10);writer.Write((Int32)30);var len = ms.Length;int[] bs = new int[len/4];byte[] bss = new byte[len];byte[] buf = ms.GetBuffer();var ot = new ST();MemCopy(bs, buf, (int)len);MemCopy(bss, buf, (int)len);MemCopy(ref ot, buf, (int)len);//注意只有結構體能這么做,class不可以 }}}Marshal對應的實現ByteToStruct,及效率對比完整程序如下:以讀取魔獸世界M2文件為例,經測試發現ByteToStruct用時為MemCopy的3倍到4倍
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using NUnit.Framework.Internal.Filters; using System; using System.Runtime.InteropServices; using System.Diagnostics;using Debug = UnityEngine.Debug; using System.Threading; using System.ComponentModel;struct Sphere {/*0x00*/public float xmin, ymin, zmin;/*0x0C*/public float xmax, ymax, zmax;/*0x18*/public float radius; };struct ModelHeader {public byte id0, id1, id2, id3;public byte ver0, ver1, ver2, ver3;public UInt32 nameLength;public UInt32 nameOfs;public UInt32 GlobalModelFlags; // 1: tilt x, 2: tilt y, 4:, 8: add another field in header, 16: ; (no other flags as of 3.1.1);public UInt32 nGlobalSequences; // AnimationRelatedpublic UInt32 ofsGlobalSequences; // A list of timestamps.public UInt32 nAnimations; // AnimationRelatedpublic UInt32 ofsAnimations; // Information about the animations in the model.public UInt32 nAnimationLookup; // AnimationRelatedpublic UInt32 ofsAnimationLookup; // Mapping of global IDs to the entries in the Animation sequences block.//UInt32 nD;//UInt32 ofsD;public UInt32 nBones; // BonesAndLookupspublic UInt32 ofsBones; // Information about the bones in this model.public UInt32 nKeyBoneLookup; // BonesAndLookupspublic UInt32 ofsKeyBoneLookup; // Lookup table for key skeletal bones.public UInt32 nVertices; // GeometryAndRenderingpublic UInt32 ofsVertices; // Vertices of the model.public UInt32 nViews; // GeometryAndRendering//UInt32 ofsViews; // Views (LOD) are now in .skins.public UInt32 nColors; // ColorsAndTransparencypublic UInt32 ofsColors; // Color definitions.public UInt32 nTextures; // TextureAndTheifAnimationpublic UInt32 ofsTextures; // Textures of this model.public UInt32 nTransparency; // H, ColorsAndTransparencypublic UInt32 ofsTransparency; // Transparency of textures.//UInt32 nI; // always unused ?//UInt32 ofsI;public UInt32 nTexAnims; // J, TextureAndTheifAnimationpublic UInt32 ofsTexAnims;public UInt32 nTexReplace; // TextureAndTheifAnimationpublic UInt32 ofsTexReplace; // Replaceable Textures.public UInt32 nTexFlags; // Render Flagspublic UInt32 ofsTexFlags; // Blending modes / render flags.public UInt32 nBoneLookup; // BonesAndLookupspublic UInt32 ofsBoneLookup; // A bone lookup table.public UInt32 nTexLookup; // TextureAndTheifAnimationpublic UInt32 ofsTexLookup; // The same for textures.public UInt32 nTexUnitLookup; // L, TextureAndTheifAnimation, seems gone after Cataclysmpublic UInt32 ofsTexUnitLookup; // And texture units. Somewhere they have to be too.public UInt32 nTransparencyLookup; // M, ColorsAndTransparencypublic UInt32 ofsTransparencyLookup; // Everything needs its lookup. Here are the transparencies.public UInt32 nTexAnimLookup; // TextureAndTheifAnimationpublic UInt32 ofsTexAnimLookup; // Wait. Do we have animated Textures? Wasn't ofsTexAnims deleted? oOpublic Sphere collisionSphere;public Sphere boundSphere;public UInt32 nBoundingTriangles; // Miscellaneouspublic UInt32 ofsBoundingTriangles;public UInt32 nBoundingVertices; // Miscellaneouspublic UInt32 ofsBoundingVertices;public UInt32 nBoundingNormals; // Miscellaneouspublic UInt32 ofsBoundingNormals;public UInt32 nAttachments; // O, Miscellaneouspublic UInt32 ofsAttachments; // Attachments are for weapons etc.public UInt32 nAttachLookup; // P, Miscellaneouspublic UInt32 ofsAttachLookup; // Of course with a lookup.public UInt32 nEvents; // public UInt32 ofsEvents; // Used for playing sounds when dying and a lot else.public UInt32 nLights; // Rpublic UInt32 ofsLights; // Lights are mainly used in loginscreens but in wands and some doodads too.public UInt32 nCameras; // S, Miscellaneouspublic UInt32 ofsCameras; // The cameras are present in most models for having a model in the Character-Tab.public UInt32 nCameraLookup; // Miscellaneouspublic UInt32 ofsCameraLookup; // And lookup-time again, unit16public UInt32 nRibbonEmitters; // U, Effectspublic UInt32 ofsRibbonEmitters; // Things swirling around. See the CoT-entrance for light-trails.public UInt32 nParticleEmitters; // V, Effectspublic UInt32 ofsParticleEmitters; // Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles.public UInt32 nUnknown; // Apparently added in models with the 8-flag only. If that flag is not set, this field does not exist!public UInt32 ofsUnknown; // An array of shorts, related to renderflags. };public class m2 : MonoBehaviour {[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]public static extern void MemCopy(byte[] dest, byte[] src, int count);//字節數組到字節數組的拷貝 [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]public static extern void MemCopy(int[] dest, byte[] src, int count);//字節數組到整形數組的拷貝 [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]static extern void MemCopy(ref ModelHeader dest, byte[] src, int count);//注意只有結構體能這么做,class不可以// Use this for initializationvoid Start () {LoadMesh ("Assets/models/creature/arcticcondor.m2");}// Update is called once per framevoid Update () {}#region public public UInt32[] globalSequences;#endregion#region privatevoid LoadMesh(string filePath){if(false == File.Exists(filePath)){Debug.LogError ("file not exist : " + filePath);return;}var bytes = File.ReadAllBytes (filePath);var buffer = new BufferedStream (new MemoryStream (bytes));var wt = new Stopwatch ();wt.Start ();var theader = new ModelHeader ();var size_header = Marshal.SizeOf (theader);MemCopy (ref theader, bytes, size_header);Debug.Log ("MemCopy------------------------" + wt.Elapsed);wt.Stop ();var wt2 = new Stopwatch ();wt2.Start ();var header = (ModelHeader)ByteToStruct (bytes, typeof(ModelHeader));Debug.Log ("ByteToStruct------------------------" + wt2.Elapsed);wt2.Stop ();if(header.id0 != 'M' || header.id1 != 'D' || header.id2 != '2' || header.id3 != '0' ){Debug.LogError ("read m2 header : invalid id0, id1, id2, id3");return;}if(header.nameOfs != 304 && header.nameOfs != 320){Debug.LogError ("Invalid model nameOfs=" + header.nameOfs);return;}// Error check// 10 1 0 0 = WoW 5.0 models (as of 15464)// 10 1 0 0 = WoW 4.0.0.12319 models// 9 1 0 0 = WoW 4.0 models// 8 1 0 0 = WoW 3.0 models// 4 1 0 0 = WoW 2.0 models// 0 1 0 0 = WoW 1.0 modelsif(bytes.Length < header.ofsParticleEmitters){Debug.LogError ("unable to load the model \"" + filePath);return;}if(header.nGlobalSequences > 0){globalSequences = new UInt32[header.nGlobalSequences];}}void RenderMesh(){}public static object ByteToStruct(byte[] bytes, Type type){int size = Marshal.SizeOf(type);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;}#endregion}?
posted on 2017-06-17 18:13 時空觀察者9號 閱讀(...) 評論(...) 編輯 收藏
總結
以上是生活随笔為你收集整理的C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UGUI 事件穿透规则
- 下一篇: Memcpy, blockcopy的进一