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 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...
随机推荐
- 相等(==)、严格相等(===)、NaN、null、undefined、空和0
(===)如果两个引用值指向同一个对象.数组.或函数,则他们是相等的.如果指向不同的对象,则他们是不相等的,尽管两个对象具有完全一样的属性. (==)如果其中一个值是true,则将其转换为1再进行比较 ...
- java的组合和继承
其实我第一次学习java 的时候根本没有听说过组合这个名词,老师也更没有讲解过,我一直以为是我自己落掉了什么知识点,其实不是的,组合这个名词暂且把它定义为一个思维性的东西吧,相信读者都接触过了,但是并 ...
- JAVA单向链表实现
JAVA单向链表实现 单向链表 链表和数组一样是一种最常用的线性数据结构,两者各有优缺点.数组我们知道是在内存上的一块连续的空间构成,所以其元素访问可以通过下标进行,随机访问速度很快,但数组也有其缺点 ...
- CSUOJ 1217 奇数个的那个数 位运算
Description 给定些数字,这些数中只有一个数出现了奇数次,找出这个数. Input 每组数据第一行n表示数字个数,1 <= n <= 2 ^ 18 且 n % 2 == 1. 接 ...
- zoj-1610线段树刷题
title: zoj-1610线段树刷题 date: 2018-10-16 16:49:47 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道简单的线段树区间染色问 ...
- CentOS7.4 关闭firewall防火墙,改用iptables
1.关闭默认的firewall防火墙 systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service ...
- luoguP2231 [HNOI2002]跳蚤
题目链接 bzoj1220: [HNOI2002]跳蚤 题解 根据裴蜀定理,不定方程的解为未知数的gcd,所以选取的n个数的gcd为1 那么n - 1个数保证没有公约数为m的约数,枚举质因数容斥 质因 ...
- ngx_lua配置及应用
一.说明 这里不对lua语言本身及其编译器运行环境等做介绍,以下所有介绍前提对lua相关有所了解. 二.ngx_lua介绍 原理 ngx_lua将Lua嵌入Nginx,可以让Nginx执行Lua脚本, ...
- hdu 2732 最大流 **
题意:题目是说一个n*m的迷宫中,有每个格子有柱子.柱子高度为0~3,高度为0的柱子是不能站的(高度为0就是没有柱子)在一些有柱子的格子上有一些蜥蜴,一次最多跳距离d,相邻格子的距离是1,只要跳出迷宫 ...
- Codeforces Round #294 (Div. 2)A - A and B and Chess 水题
A. A and B and Chess time limit per test 1 second memory limit per test 256 megabytes input standard ...