zoukankan      html  css  js  c++  java
  • 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; // AnimationRelated
        public UInt32 ofsGlobalSequences; // A list of timestamps.
        public UInt32 nAnimations; // AnimationRelated
        public UInt32 ofsAnimations; // Information about the animations in the model.
        public UInt32 nAnimationLookup; // AnimationRelated
        public UInt32 ofsAnimationLookup; // Mapping of global IDs to the entries in the Animation sequences block.
        //UInt32 nD;
        //UInt32 ofsD;
        public UInt32 nBones; // BonesAndLookups
        public UInt32 ofsBones; // Information about the bones in this model.
        public UInt32 nKeyBoneLookup; // BonesAndLookups
        public UInt32 ofsKeyBoneLookup; // Lookup table for key skeletal bones.
    
        public UInt32 nVertices; // GeometryAndRendering
        public UInt32 ofsVertices; // Vertices of the model.
        public UInt32 nViews; // GeometryAndRendering
        //UInt32 ofsViews; // Views (LOD) are now in .skins.
    
        public UInt32 nColors; // ColorsAndTransparency
        public UInt32 ofsColors; // Color definitions.
    
        public UInt32 nTextures; // TextureAndTheifAnimation
        public UInt32 ofsTextures; // Textures of this model.
    
        public UInt32 nTransparency; // H,  ColorsAndTransparency
        public UInt32 ofsTransparency; // Transparency of textures.
        //UInt32 nI;   // always unused ?
        //UInt32 ofsI;
        public UInt32 nTexAnims;    // J, TextureAndTheifAnimation
        public UInt32 ofsTexAnims;
        public UInt32 nTexReplace; // TextureAndTheifAnimation
        public UInt32 ofsTexReplace; // Replaceable Textures.
    
        public UInt32 nTexFlags; // Render Flags
        public UInt32 ofsTexFlags; // Blending modes / render flags.
        public UInt32 nBoneLookup; // BonesAndLookups
        public UInt32 ofsBoneLookup; // A bone lookup table.
    
        public UInt32 nTexLookup; // TextureAndTheifAnimation
        public UInt32 ofsTexLookup; // The same for textures.
    
        public UInt32 nTexUnitLookup;        // L, TextureAndTheifAnimation, seems gone after Cataclysm
        public UInt32 ofsTexUnitLookup; // And texture units. Somewhere they have to be too.
        public UInt32 nTransparencyLookup; // M, ColorsAndTransparency
        public UInt32 ofsTransparencyLookup; // Everything needs its lookup. Here are the transparencies.
        public UInt32 nTexAnimLookup; // TextureAndTheifAnimation
        public UInt32 ofsTexAnimLookup; // Wait. Do we have animated Textures? Wasn't ofsTexAnims deleted? oO
    
        public Sphere collisionSphere;
        public Sphere boundSphere;
    
        public UInt32 nBoundingTriangles; // Miscellaneous
        public UInt32 ofsBoundingTriangles;
        public UInt32 nBoundingVertices; // Miscellaneous
        public UInt32 ofsBoundingVertices;
        public UInt32 nBoundingNormals; // Miscellaneous
        public UInt32 ofsBoundingNormals;
    
        public UInt32 nAttachments; // O, Miscellaneous
        public UInt32 ofsAttachments; // Attachments are for weapons etc.
        public UInt32 nAttachLookup; // P, Miscellaneous
        public 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; // R
        public UInt32 ofsLights; // Lights are mainly used in loginscreens but in wands and some doodads too.
        public UInt32 nCameras; // S, Miscellaneous
        public UInt32 ofsCameras; // The cameras are present in most models for having a model in the Character-Tab.
        public UInt32 nCameraLookup; // Miscellaneous
        public UInt32 ofsCameraLookup; // And lookup-time again, unit16
        public UInt32 nRibbonEmitters; // U, Effects
        public UInt32 ofsRibbonEmitters; // Things swirling around. See the CoT-entrance for light-trails.
        public UInt32 nParticleEmitters; // V, Effects
        public 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 initialization
        void Start () {
            LoadMesh ("Assets/models/creature/arcticcondor.m2");
        }
        
        // Update is called once per frame
        void Update () {
            
        }
    
    #region public 
        public UInt32[] globalSequences;
    
    #endregion
    
    #region private
        void 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 models
    
            if(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
    
    }
  • 相关阅读:
    iOS 从0到1搭建高可用App框架
    ios 判断用户是否开启权限---并跳转设置
    用PHP做服务器接口客户端用http协议POST访问安全性一般怎么做
    示例浅谈PHP与手机APP开发,即API接口开发
    iOS百度地图简单使用详解
    UICollectionViewCell「居左显示」
    IOS中使用百度地图定位后获取城市坐标,城市名称,城市编号信息
    iOS开发融云即时通讯集成详细步骤
    iOS
    修改hosts文件
  • 原文地址:https://www.cnblogs.com/timeObjserver/p/7040966.html
Copyright © 2011-2022 走看看