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));
writer.Write((Int32));
var len = ms.Length;
int[] bs = new int[len/];
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 != '' || header.id3 != '' ){
Debug.LogError ("read m2 header : invalid id0, id1, id2, id3");
return;
} if(header.nameOfs != && header.nameOfs != ){
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 > ){
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, , structPtr, size);
//将内存空间转换为目标结构体
object obj = Marshal.PtrToStructure(structPtr, type);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
return obj;
} #endregion }
C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比的更多相关文章
- 问题:C# params类型参数;结果:C#的参数类型:params、out和ref
C#的参数类型:params.out和ref PS:由于水平有限,难免会有错误和遗漏,欢迎各位看官批评和指正,谢谢~ 首先回顾一下C#声明一个方法的语法和各项元素,[]代表可选 [访问修饰符] 返回值 ...
- python限定方法参数类型、返回值类型、变量类型等
typing模块的作用 自python3.5开始,PEP484为python引入了类型注解(type hints) 类型检查,防止运行时出现参数和返回值类型.变量类型不符合. 作为开发文档附加说明,方 ...
- 可以使用可用的服务和参数调用在“eWorld.WCFImplement.ServiceImplement.ImageArchiveService”类型上使用“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”找到的构造函数: 无法解析参数'eWorld.WCFBLL.ImageArchive.IDocumentOperation
可以使用可用的服务和参数调用在“eWorld.WCFImplement.ServiceImplement.ImageArchiveService”类型上使用“Autofac.Core.Activato ...
- C++11 图说VS2013下的引用叠加规则和模板参数类型推导规则
背景: 最近在学习C++STL,出于偶然,在C++Reference上看到了vector下的emplace_back函数,不想由此引发了一系列的“探索”,于是就有了现在这篇博文. 前言: ...
- [c++][语言语法]函数模板和模板函数 及参数类型的运行时判断
参考:http://blog.csdn.net/beyondhaven/article/details/4204345 参考:http://blog.csdn.net/joeblackzqq/arti ...
- c语言参数类型
今天看ntcip源码时看到,函数参数有点不一样.在函数实现时,没有括号中没有指明参数类型.注意这里说的是函数实现,不是说函数声明.这里在函数列表括号后面做了类型的说明,以前看到过,没想起来,今天做个记 ...
- C# WebService的简单和复杂参数类型和结果的JSON格式
Jquery作为一款优秀的JS框架,简单易用的特性就不必说了.在实际的开发过程中,使用JQ的AJAX函数调用WebService 的接口实现AJAX的功能也成了一种比较普遍的技术手段了.WebServ ...
- webservice调用接口,接口返回数组类型
1. 其中sendSyncMsg1接口是方法名,Vector实现了List接口,xml是sendSyncMsg1的方法形参 Service service = new Service(); Call ...
- 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针
您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...
随机推荐
- thinkphp条用函数与类库
手册上说的很冗余,没看懂,下面简单的讲一下具体用法. 函数调用: lib公共函数库叫 common.php App/common/common.php 分组模块下的公共函数库叫 function.ph ...
- 子查询中的NULL问题
子查询返回有单行,多行和null值:适用于单行子查询的比较运算符是=,>,>=,<,<=<>和!=.适用于多行子查询的比较运算符是in,not in,any和any ...
- 基于spring-boot的应用程序的单元+集成测试方案
目录 概述 概念解析 单元测试和集成测试 Mock和Stub 技术实现 单元测试 测试常规的bean 测试Controller 测试持久层 集成测试 从Controller开始测试 从中间层开始测试 ...
- 01-学前入门.Net两种交换模式
C/S:客户机(Client)/服务器模式(Server)Winfrom应用程序 B/S:浏览器(Browser)/服务器模式(Server)Internet应用模式
- LuoguP5017 摆渡车 $dp$
题意 戳这里 吐槽 听同学说今年\(pjT3\)很难,于是就去看了下. 一眼斜率优化...为什么\(n,m\)这么小啊... 感觉这题出的还是不错的. Solution 首先我们先转化一波题意:给出数 ...
- BZOJ 4066 简单题(KD树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4066 [题目大意] 要求维护矩阵内格子加点和矩阵查询 [题解] 往KD树上加权值点,支 ...
- Python168的学习笔记2
关于for循环,其实质是利用被循环对象的__iter__,或者__getitem__属性接口,由可迭代对象得到迭代器.for循环就是不断调用.next(),直到最终捕获到stop. import re ...
- BZOJ 1191: [HNOI2006]超级英雄Hero 匈牙利算法
1191: [HNOI2006]超级英雄Hero Time Limit: 2 Sec Memory Limit: 256 MBSubmit: xxx Solved: 2xx 题目连接 http:/ ...
- HDU 1269 移动城堡 联通分量 Tarjan
迷宫城堡 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- windows下python2.7.14版本的安装
本文主要对window下如何安装Python进行图解说明 步骤一.从官网下载相应的版本(本文以2.7.14为例),https://www.python.org/downloads/release/py ...