基于C++/CLI的VB.NET/C#内存指针访问类库

大家知道,VB.NET/C#在指针的使用上是受到很多限制的。虽然C#提供了unsafe代码的指针访问,但还是有不少限制。.NET Framework的类库提供了GCHandle类库和Marshal命名空间内存访问方法,但一来速度比较慢,二来访问时(譬如基于数组和结构的数据转化)需要重新创建对象。

因此,我用C++/CLI写了个内存指针访问类库,解决了VB.NET内存指针访问的难题。

下面是一个字符串拷贝示例:

        Console.WriteLine("拷贝字符串示例")
        Using ptr As Pointer = Pointer.Lock(txtsrc.Text)
            '方法1,直接进行字符串复制
            txtdst.Text = ptr.CopyToString(txtsrc.TextLength)

            Console.WriteLine("Pointer.CopyToString:{0}", txtdst.Text)

            '方法2,通过CopyToObject的泛型方法复制字符串
            Dim strdst As String = New String(" "c, txtsrc.TextLength)
            txtdst.Text = ptr.CopyToObject(Of String)(strdst)
            Console.WriteLine("Pointer.CopyToObject:{0}", txtdst.Text)

        End Using '解锁对象,相当于ptr.UnLock()
        '方法3,用 Shared 的 Copy 方法进行字符串复制。
        Dim strdsts As String = New String(" "c, txtsrc.TextLength)
        Pointer.Copy(strdsts, txtsrc.Text, 0, 0, txtsrc.TextLength * 2) ' 1 Char = 2 Bytes
        txtdst.Text = strdsts
        ConsoleWriteLine("Pointer.Copy:{0}", txtdst.Text)


数据类型的转换:

        '测试字符串到整数
        Console.WriteLine()
        Console.WriteLine("读取整数:")
        Using ptr As Pointer = Pointer.Lock(txtsrc.Text)
            Dim lll As Integer = txtsrc.TextLength << 1 '获取字节长度

            ConsoleWrite("按照字节读取数据(Bytes), Pointer.Item     : ")
            For i As Integer = 0 To lll - 1
                Console.Write("{0:X2} ", ptr(i))
            Next
            Console.WriteLine()

            ConsoleWrite("按照字读取数据  (Char),  Pointer.Int16Item: ")
            For i As Integer = 0 To (lll >> 1) - 1
                Console.Write("{0} ", ptr.CharItem(i))
            Next
            Console.WriteLine()

            ConsoleWrite("按照字读取数据  (Short), Pointer.Int16Item: ")
            For i As Integer = 0 To (lll >> 1) - 1
                ConsoleWrite("{0:X4} ", ptr.Int16Item(i))
            Next
            ConsoleWriteLine()

            Console.Write("按照双字读取数据(Int  ), Pointer.Int32Item: ")
            For i As Integer = 0 To (lll >> 2) - 1
                Console.Write("{0:X8} ", ptr.Int32Item(i))
            Next
            Console.WriteLine()

            Console.Write("按照四字读取数据(Long ), Pointer.Int64Item: ")
            For i As Integer = 0 To (lll >> 3) - 1
                Console.Write("{0:X16} ", ptr.Int64Item(i))
            Next
            Console.WriteLine()

            Console.WriteLine()

            ConsoleWriteLine("拷贝到数组:")
            ConsoleWrite("Bytes  :")
            Dim bytes As Byte() = New Byte(lll - 1) {}

            ptr.CopyToArray(bytes, 0, lll)
            'Pointer.Copy(bytes, ptr, 0, 0, l) '这样也可以
            Console.WriteLine(BitConverter.ToString(bytes))

            Console.Write("Short  :")
            Dim shorts As Short() = New Short((lll >> 1) - 1) {}

            Pointer.Copy(shorts, ptr, 0, 0, lll) '这样也可以
            For i As Integer = 0 To shorts.Length - 1
                Console.Write("{0:X4} ", shorts(i))
            Next
            Console.WriteLine()

            Console.Write("Integer:")
            Dim ints As Integer() = New Integer((lll >> 2) - 1) {}

            Pointer.Copy(ints, ptr, 0, 0, lll) '这样也可以
            For i As Integer = 0 To ints.Length - 1
                Console.Write("{0:X8} ", ints(i))
            Next
            Console.WriteLine()

            Console.Write("Long   :")
            Dim longs As Long() = New Long((lll >> 3) - 1) {}

            Pointer.Copy(longs, ptr, 0, 0, lll) '这样也可以
            For i As Integer = 0 To longs.Length - 1
                Console.Write("{0:X16} ", longs(i))
            Next
            Console.WriteLine()

            Console.WriteLine("数据回写:")
            Dim sl As Short() = New Short() {&H31, &H32, &H33, &H2020, &H3031}

            Pointer.Copy(ptr, sl, 0, 0, sl.Length << 2)

            ptr.CopyToArray(bytes, 0, lll)
            'Pointer.Copy(bytes, ptr, 0, 0, l) '这样也可以
            Console.WriteLine("写入值(Short):0x31, 0x32, 0x33, 0x2020, 0x3031")
            Console.WriteLine("目标值(Byte ):{0}", BitConverter.ToString(bytes))


        End Using

        Console.WriteLine("对象类型转换:")

        Dim pt As Point = New Point(12345, 67890)         Console.WriteLine("源对象类型:Point,{0}", pt.ToString())         Using ptr = Pointer.Lock(pt)             Console.WriteLine("转换为Pointf:{0}", ptr.CopyToObject(Of PointF)().ToString())             Console.WriteLine("转换为PointTest:{0}", ptr.CopyToObject(Of PointTest)().ToString())         End Using

其中,上面的PointTest类结构如下,与Point结构的不同是PointTest为类,Point为结构(值类型):

    <StructLayout(LayoutKind.Sequential)> _
    Private Class PointTest
        Public x As Integer
        Public y As Integer

        Public Overrides Function ToString() As String
            Return String.Format("x={0},y={1}", x, y)
        End Function
    End Class

 
与Marshal.Copy的速度比较。

由于用了内嵌汇编,所以拷贝速度还是比较可观的,起码比Marshal.Copy快上一点。


Pointer.Copy 循环1000000次,耗时:   2028003 Ticks
Marshal.Copy 循环1000000次,耗时:   2340004 Ticks

而且支持数组到数组、数组到指针、数组到对象、指针到指针、指针到数组、指针到对象、对象到数组、对象到指针、对象到对象等拷贝方式。

下面是比较代码:

        Console.WriteLine()
        Console.WriteLine("与Marshal.Copy比较拷贝速度:")

        Dim buff1 As Integer() = New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
        Dim buff2 As Byte() = New Byte(buff1.Length << 2) {}
        Dim ds As Long
        Dim cnt As Integer = 1000000 '循环次数
        Dim l As Integer = buff2.Length
        Using ptr = Pointer.Lock(Of Integer())(buff1)
            Console.Write("Pointer.Copy 循环{0}次,", cnt)
            ds = Now.Ticks
            Using dtr = Pointer.Lock(Of Byte())(buff2)
                For i As Integer = 1 To cnt
                    Pointer.Copy(dtr, ptr, 0, 0, l)
                Next
            End Using
            Console.WriteLine("耗时:{0} Ticks", (Now.Ticks - ds).ToString().PadLeft(10, " "c))

            Console.Write("Marshal.Copy 循环{0}次,", cnt)
            ds = Now.Ticks
            For i As Integer = 1 To cnt
                Marshal.Copy(ptr.Address, buff2, 0, l)
            Next
            Console.WriteLine("耗时:{0} Ticks", (Now.Ticks - ds).ToString().PadLeft(10, " "c))

        End Using


 

C++/CLI源代码:

主类(CWOOD.Pointer.h):

// CWOOD.Pointer.h
#include "MemoryCopy.h"

#pragma once

using namespace System;
using namespace System::Runtime::InteropServices;

namespace CWOOD
{

#pragma region Pointer

	public ref class Pointer
	{
	private:
		int locptr,farptr;
		GCHandle^ SafeHandle;
		
		Byte*		BytePtr;
		Char*		CharPtr;

		short*		Int16Ptr;
		int*		Int32Ptr;
		Int64*		Int64Ptr;

		unsigned short*		UInt16Ptr;
		unsigned int*		UInt32Ptr;
		UInt64*		UInt64Ptr;

		float*		FloatPtr;
		double*		DoublePtr;
		
		int sz;

	public:
#pragma region 构造函数
		//用预分配内存的方式定义一个新的指针对象
		Pointer(int BytesSize)
		{
			locptr   = (int)Marshal::AllocHGlobal(BytesSize);
			farptr   = locptr;
			
			BytePtr  = (Byte*)farptr;
			CharPtr  = (Char*)farptr;
			Int16Ptr = (short*)farptr;
			Int32Ptr = (int*)farptr;
			Int64Ptr = (Int64*)farptr;

			UInt16Ptr = (unsigned short*)farptr;
			UInt32Ptr = (unsigned int*)farptr;
			UInt64Ptr = (UInt64*)farptr;
			FloatPtr = (float*)farptr;
			DoublePtr = (double*)farptr;

		}

		//用已有指针创建一个指针对象
		Pointer(IntPtr AddressPtr)
		{
			locptr   = 0;
			farptr   = (int)AddressPtr;
			BytePtr  = (Byte*)farptr;
			CharPtr  = (Char*)farptr;
			Int16Ptr = (short*)farptr;
			Int32Ptr = (int*)farptr;
			Int64Ptr = (Int64*)farptr;

			UInt16Ptr = (unsigned short*)farptr;
			UInt32Ptr = (unsigned int*)farptr;
			UInt64Ptr = (UInt64*)farptr;
			FloatPtr = (float*)farptr;
			DoublePtr = (double*)farptr;
		}

		Pointer(String^ value)
		{
			locptr      = -1;
			SafeHandle  = GCHandle::Alloc(value,GCHandleType::Pinned);
			farptr      = (int)SafeHandle->AddrOfPinnedObject();
			BytePtr	    = (Byte*)farptr;
			CharPtr	    = (Char*)farptr;
			Int16Ptr    = (short*)farptr;
			Int32Ptr    = (int*)farptr;
			Int64Ptr    = (Int64*)farptr;

			UInt16Ptr = (unsigned short*)farptr;
			UInt32Ptr = (unsigned int*)farptr;
			UInt64Ptr = (UInt64*)farptr;
			FloatPtr = (float*)farptr;
			DoublePtr = (double*)farptr;
		}

#pragma endregion

#pragma region 析构函数
		~Pointer()
		{
			if(locptr == farptr)
			{
				Marshal::FreeHGlobal((IntPtr)locptr);
			}
			else if(locptr == -1)
			{
				if(SafeHandle != nullptr)SafeHandle->Free();
			}
			locptr = 0;
			farptr = 0;
		}
#pragma endregion

#pragma region 属性
		property IntPtr Address
		{
			IntPtr get()
			{
				return (IntPtr)farptr;
			}
		}

		property Byte default[int]
		{
			Byte get(int offset)
			{
				return BytePtr[offset];
			}
			void set(int offset, Byte value)
			{
				BytePtr[offset] = value;
			}
		}

		property Char CharItem[int]
		{
			Char get(int offset)
			{
				return CharPtr[offset];
			}
			void set(int offset, Char value)
			{
				CharPtr[offset] = value;
			}
		}


		property short Int16Item[int]
		{
			short get(int offset)
			{
				return Int16Ptr[offset];
			}
			void set(int offset, short value)
			{
				Int16Ptr[offset] = value;
			}
		}

		property int Int32Item[int]
		{
			int get(int offset)
			{
				return Int32Ptr[offset];
			}
			void set(int offset, int value)
			{
				Int32Ptr[offset] = value;
			}
		}


		property Int64 Int64Item[int]
		{
			Int64 get(int offset)
			{
				return Int64Ptr[offset];
			}
			void set(int offset, Int64 value)
			{
				Int64Ptr[offset] = value;
			}
		}

		property unsigned short UInt16Item[int]
		{
			unsigned short get(int offset)
			{
				return Int16Ptr[offset];
			}
			void set(int offset, unsigned short value)
			{
				Int16Ptr[offset] = value;
			}
		}

		property unsigned int UInt32Item[int]
		{
			unsigned int get(int offset)
			{
				return Int32Ptr[offset];
			}
			void set(int offset, unsigned int value)
			{
				Int32Ptr[offset] = value;
			}
		}

		property UInt64 UInt64Item[int]
		{
			UInt64 get(int offset)
			{
				return Int64Ptr[offset];
			}
			void set(int offset, UInt64 value)
			{
				Int64Ptr[offset] = value;
			}
		}

		property ValueType^ ValueTypeItem[int]
		{
			ValueType^ get(int offset)
			{
				return BytePtr[offset<<sizeof(ValueType^)];
			}
			/*void set(int offset, ValueType^ value)
			{
				sz = sizeof(int);
				BytePtr[offset<<sz] = value;
			}*/
		}
#pragma endregion

#pragma region 公共方法


		void UnLock()
		{
			this->~Pointer();
		}

		static void UnLock(Pointer^ point)
		{
			point->~Pointer();
		}

		/**<summary>用指定数据长度创建一个 Pointer 对象</summary>
		///<remarks></remarks>
		///<param name="size">申请内存的长度</param>
		///<returns></returns>
		static Pointer^ FromSize(int size)
		{
			return gcnew Pointer(size);
		}

		/**<summary> 由指定内存地址创建一个可操作的 Pointer 对象</summary>
		///<remarks></remarks>
		///<param name="Address">内存地址</param>
		///<returns></returns>
		static Pointer^ FromAddress(IntPtr Address)
		{
			return gcnew Pointer(Address);
		}


		/**<summary>锁定一个值类型数组,以便进行内存操作</summary>
		///<remarks>一个值类型数据</remarks>
		///<param name="value">待锁定的数组</param>
		///<returns>返回锁定该数组的 Pointer 对象</returns>
		generic<class T>
		static Pointer^ Lock(array<T>^ value)
		{
			if(IsValueType(value))
			{
				pin_ptr<array<T>^> ptr = &value;
				Pointer^ t     = gcnew Pointer((IntPtr)ptr);
				return t;
			}
			else
			{
				GCHandle hnd  = GCHandle::Alloc(value,GCHandleType::Pinned);
				IntPtr ptr    = hnd.AddrOfPinnedObject();
				Pointer^ t     = gcnew Pointer(ptr);
				t->locptr = -1;
				t->SafeHandle = hnd;

				return t;
			}
		}

		/**<summary>锁定字符串,以便进行内存操作</summary>
		///<remarks></remarks>
		///<param name="value">待锁定的数组</param>
		///<returns>返回锁定该数组的 Pointer 对象</returns>
		static Pointer^ Lock(String^ value )
		{
			return gcnew Pointer(value);
		}

		/**<summary>锁定无符号长整数数组,以便进行内存操作</summary>
		///<remarks>一个无符号长整数型数字,8字节大小</remarks>
		///<param name="value">待锁定的数组</param>
		///<returns>返回锁定该数组的 Pointer 对象</returns>
		generic<class T>
		static Pointer^ Lock(T% value )
		{

			if(IsValueType(value))
			{
				pin_ptr<T> ptr = &value;
				Pointer^ t     = gcnew Pointer((IntPtr)ptr);
				return t;
			}
			else
			{
				GCHandle hnd  = GCHandle::Alloc(value,GCHandleType::Pinned);
				IntPtr ptr    = hnd.AddrOfPinnedObject();
				Pointer^ t     = gcnew Pointer(ptr);
				t->locptr = -1;
				t->SafeHandle = hnd;

				return t;
			}
		}

		/**<summary>将数据复制到目标对象</summary>
		///<remarks>不支持字符串、数组等</remarks>
		///<return>数据复制后的对象</return>
		generic<class T>
		T CopyToObject()
		{
			int size;
			if((T::typeid)->IsValueType)
			{
				T obj;
				size = sizeof(obj);
				pin_ptr<T> dest = &obj;
				Byte* destptr = (Byte*)dest;

				MemoryCopy::CopySD(destptr,BytePtr,size);

				return obj;
			}
			else
			{
				if((T::typeid) == (String::typeid))
				{
					return (T)String::Empty;//不支持字符串、数组等
				}
				else
				{
					T obj = Activator::CreateInstance<T>();
					size = Marshal::SizeOf(obj);
					GCHandle hnd  = GCHandle::Alloc(obj,GCHandleType::Pinned);
					IntPtr ptr    = hnd.AddrOfPinnedObject();
					MemoryCopy::CopySD((Byte*)(int)ptr,BytePtr,size);
					hnd.Free();
					return obj;
				}
			}
		}

		/**<summary>将数据复制到目标对象</summary>
		///<remarks></remarks>
		///<param name="obj">目标对象</param>
		///<return>数据复制后的对象</return>
		generic<class T>
		T CopyToObject(T% obj)
		{
			int size;
			
			if(IsValueType(obj))
			{
				size = sizeof(obj);
				pin_ptr<T> dest = &obj;
				Byte* destptr = (Byte*)dest;

				MemoryCopy::CopySD(destptr,BytePtr,size);

				return obj;
			}
			else
			{
				if(isinst<String^,Object^>((Object^)obj))//如果是字符串,要特殊处理
				{
					size = ((String^)obj)->Length<<2;
				}
				else
				{
					size = Marshal::SizeOf(obj);
				}
				
				GCHandle hnd  = GCHandle::Alloc(obj,GCHandleType::Pinned);
				IntPtr ptr    = hnd.AddrOfPinnedObject();
				MemoryCopy::CopySD((Byte*)(int)ptr,BytePtr,size);
				hnd.Free();
				return obj;
			}
		}

		/**<summary>将数据复制到目标数组</summary>
		///<remarks></remarks>
		///<param name="obj">目标数组</param>
		///<return>数据复制后的数组</return>
		generic<class T>
		array<T>^ CopyToObject(array<T>^ obj)
		{
			int size;
			
			if (obj == nullptr || obj->Length==0) return obj;

			size = obj->Length * SizeOf(obj[0]);
			GCHandle hnd  = GCHandle::Alloc(obj,GCHandleType::Pinned);
			IntPtr ptr    = hnd.AddrOfPinnedObject();
			MemoryCopy::CopySD((Byte*)(int)ptr,BytePtr,size);
			hnd.Free();
			return obj;
		}

		/**<summary>将数据复制到目标数组</summary>
		///<remarks></remarks>
		///<param name="obj">目标数组</param>
		///<param name="offset">偏移量,以数组单位长度为度量值</param>
		///<param name="length">复制长度,以数组单位长度为度量值</param>
		///<return>数据复制后的数组</return>
		generic<class T>
		array<T>^ CopyToArray(array<T>^ obj, int offset, int length)
		{
			int size;
			
			if (obj == nullptr || obj->Length==0 || offset > obj->Length || length <= 0) return obj;

			if(length + offset > obj->Length)length = obj->Length -  offset;
			
			size = length * SizeOf(obj[0]);
			GCHandle hnd  = GCHandle::Alloc(obj,GCHandleType::Pinned);
			IntPtr ptr    = hnd.AddrOfPinnedObject();
			MemoryCopy::CopySD((Byte*)(int)ptr,BytePtr,size);
			hnd.Free();
			return obj;
		}

		/**<summary>将数据复制到目标对象</summary>
		///<remarks></remarks>
		///<param name="l">字符串长度</param>
		///<return>数据复制后的对象</return>
		String^ CopyToString(int l)
		{
			String^ d = gcnew String(0x0,l);
			GCHandle hnd  = GCHandle::Alloc(d,GCHandleType::Pinned);
			IntPtr ptr    = hnd.AddrOfPinnedObject();
			MemoryCopy::CopySD((unsigned char*)(int)ptr,BytePtr,l<<1);
			hnd.Free();
			return d;
		}

		/**<summary>从对象拷贝数据</summary>
		///<remarks></remarks>
		///<param name="obj">待拷贝对象</param>
		generic<class T>
		void CopyFromObject(T% obj)
		{

			int size;
			if(IsValueType(obj))
			{
				pin_ptr<T> src = &obj;
				Byte* srcptr = (Byte*)src;
				int size = sizeof(obj);

				MemoryCopy::CopySD(BytePtr,srcptr,size);
			}
			else
			{
				size = Marshal::SizeOf(obj);
				GCHandle hnd  = GCHandle::Alloc(obj,GCHandleType::Pinned);
				IntPtr ptr    = hnd.AddrOfPinnedObject();
				MemoryCopy::CopySD(BytePtr,(Byte*)(int)ptr,size);
				hnd.Free();
			}
		}

		/**<summary>从数组拷贝数据</summary>
		///<remarks></remarks>
		///<param name="obj">待拷贝数组</param>
		generic<class T>
		void CopyFromObject(array<T>^ obj)
		{

			int size = obj->Length * SizeOf(obj[0]);
			GCHandle hnd  = GCHandle::Alloc(obj,GCHandleType::Pinned);
			IntPtr ptr    = hnd.AddrOfPinnedObject();
			MemoryCopy::CopySD(BytePtr,(Byte*)(int)ptr,size);
			hnd.Free();
		}

		/**<summary>从字符串拷贝数据</summary>
		///<remarks></remarks>
		///<param name="value">待拷贝字符串</param>
		void CopyFromString(String^ value)
		{
			GCHandle hnd = GCHandle::Alloc(value,GCHandleType::Pinned);
			IntPtr   ptr = hnd.AddrOfPinnedObject();
			Byte* srcptr = (Byte*)(int)ptr;
			/*pin_ptr<String^> src = &value;
			Byte* srcptr = (Byte*)src;*/
			int size = (value->Length)<<1;

			MemoryCopy::CopySD(BytePtr,srcptr,size);
			hnd.Free();
		}

		/**<summary>将数据从一对象复制到另一对象</summary>
		///<remarks></remarks>
		///<param name="Dest">目标对象</param>
		///<param name="Src">原始对象</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		generic<class T1, class T2>
		static void Copy(T1% Dest, T2% Src, int BytesLength)
		{
			Pointer^ src = Pointer::Lock(Src);
			Pointer^ dst = Pointer::Lock(Dest);

			MemoryCopy::CopySD(dst->BytePtr,  src->BytePtr, BytesLength);

			delete src;
			delete dst;
		}

		/**<summary>将数据从一对象复制到另一对象</summary>
		///<remarks></remarks>
		///<param name="Dest">目标对象</param>
		///<param name="Src">原始对象</param>
		///<param name="DestBytesOffset">目标对象的目标内存地址偏移(单位:字节数)</param>
		///<param name="SrcBytesOffset">原始对象待复制数据的内存地址偏移(单位:字节数)</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		generic<class T1, class T2>
		static void Copy(T1% Dest, T2% Src, int DestBytesOffset, int SrcBytesOffset, int BytesLength)
		{
			Pointer^ src = Pointer::Lock(Src);
			Pointer^ dst = Pointer::Lock(Dest);

			MemoryCopy::CopySD(dst->BytePtr + DestBytesOffset,  src->BytePtr + SrcBytesOffset, BytesLength);

			delete src;
			delete dst;
		}

		/**<summary>将数据从 Pointer 对象复制到指定对象</summary>
		///<remarks></remarks>
		///<param name="Dest">指定目标对象</param>
		///<param name="Src">原始 Pointer 对象</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		generic<class T>
		static void Copy(T% Dest, Pointer^ Src, int BytesLength)
		{
			Pointer^ dst = Pointer::Lock(Dest);
			 
			MemoryCopy::CopySD(dst->BytePtr, Src->BytePtr, BytesLength);
			delete dst;
		}

		/**<summary>将数据从 Pointer 对象复制到指定对象</summary>
		///<remarks></remarks>
		///<param name="Dest">指定目标对象</param>
		///<param name="Src">原始 Pointer 对象</param>
		///<param name="DestBytesOffset">目标对象的目标内存地址偏移(单位:字节数)</param>
		///<param name="SrcBytesOffset">原始 Pointer 对象待复制数据的内存地址偏移(单位:字节数)</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		generic<class T>
		static void Copy(T% Dest, Pointer^ Src, int DestBytesOffset, int SrcBytesOffset, int BytesLength)
		{
			Pointer^ dst = Pointer::Lock(Dest);
			 
			MemoryCopy::CopySD(dst->BytePtr + DestBytesOffset, (Src->BytePtr)+SrcBytesOffset, BytesLength);
			delete dst;
		}

		/**<summary>将数据从指定对象复制到目标 Pointer 对象</summary>
		///<remarks></remarks>
		///<param name="Dest">目标 Pointer 对象</param>
		///<param name="Src">原始对象</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		generic<class T>
		static void Copy(Pointer^ Dest, T% Src, int BytesLength)
		{
			Pointer^ src = Pointer::Lock(Src);
			 
			MemoryCopy::CopySD(Dest->BytePtr, src->BytePtr, BytesLength);
			delete src;
		}

		/**<summary>将数据从指定对象复制到目标 Pointer 对象</summary>
		///<remarks></remarks>
		///<param name="Dest">目标 Pointer 对象</param>
		///<param name="Src">原始对象</param>
		///<param name="DestBytesOffset">目标 Pointer 对象的目标内存地址偏移(单位:字节数)</param>
		///<param name="SrcBytesOffset">原始对象待复制数据的内存地址偏移(单位:字节数)</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		generic<class T>
		static void Copy(Pointer^ Dest, T% Src, int DestBytesOffset, int SrcBytesOffset, int BytesLength)
		{
			Pointer^ src = Pointer::Lock(Src);
			 
			MemoryCopy::CopySD(Dest->BytePtr + DestBytesOffset, src->BytePtr + SrcBytesOffset, BytesLength);
			delete src;
		}

		/**<summary>将数据从原始 Pointer 对象复制到目标 Pointer 对象</summary>
		///<remarks></remarks>
		///<param name="Dest">目标 Pointer 对象</param>
		///<param name="Src">原始 Pointer 对象</param>
		///<param name="DestBytesOffset">目标 Pointer 对象的目标内存地址偏移(单位:字节数)</param>
		///<param name="SrcBytesOffset">原始 Pointer 对象待复制数据的内存地址偏移(单位:字节数)</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		static void Copy(Pointer^ Dest, Pointer^ Src, int DestBytesOffset, int SrcBytesOffset, int BytesLength)
		{
			MemoryCopy::CopySD(Dest->BytePtr + DestBytesOffset, Src->BytePtr + SrcBytesOffset, BytesLength);
		}

		/**<summary>内存数据复制</summary>
		///<remarks></remarks>
		///<param name="DestPtr">目标内存地址</param>
		///<param name="SrcPtr">原始内存地址</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		static void Copy(IntPtr DestPtr, IntPtr SrcPtr, int BytesLength)
		{
			MemoryCopy::CopySD((unsigned char*)(int)DestPtr, (unsigned char*)(int)SrcPtr, BytesLength);
		}

		/**<summary>将数据从一内存地址复制到另一内存地址</summary>
		///<remarks></remarks>
		///<param name="DestPtr">目标内存地址</param>
		///<param name="SrcPtr">原始内存地址</param>
		///<param name="DestBytesOffset">目标 Pointer 对象的目标内存地址偏移(单位:字节数)</param>
		///<param name="SrcBytesOffset">原始 Pointer 对象待复制数据的内存地址偏移(单位:字节数)</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		static void Copy(IntPtr DestPtr, IntPtr SrcPtr, int DestBytesOffset, int SrcBytesOffset, int BytesLength)
		{
			MemoryCopy::CopySD((unsigned char*)(int)DestPtr + DestBytesOffset, (unsigned char*)(int)SrcPtr + SrcBytesOffset, BytesLength);
		}

		/**<summary>将数据从一内存地址复制到另一内存地址</summary>
		///<remarks>托管模式,运行速度比较慢</remarks>
		///<param name="d">目标内存地址</param>
		///<param name="s">原始内存地址</param>
		///<param name="l">待复制数据的字节数</param>
		static void SafeCopy(IntPtr d, IntPtr s, int l)
		{
			int *pd = (int *)(int)d;
			int *ps = (int *)(int)s;
			int i = 0;

			for (i = 0; i < l / 4; i++)
				*pd++ = *ps++;

			for (i = 0; i < l % 4; i++)
				*(char *)pd++ = *(char *)ps++;
		}

		/**<summary>将数据从一 Pointer 对象复制到另一Pointer 对象</summary>
		///<remarks>托管模式,运行速度比较慢</remarks>
		///<param name="Dest">目标 Pointer 对象</param>
		///<param name="Src">原始 Pointer 对象</param>
		///<param name="DestBytesOffset">目标 Pointer 对象的目标内存地址偏移(单位:字节数)</param>
		///<param name="SrcBytesOffset">原始 Pointer 对象待复制数据的内存地址偏移(单位:字节数)</param>
		///<param name="BytesLength">待复制数据的字节数</param>
		static void SafeCopy(Pointer^ Dest, Pointer^ Src, int DestBytesOffset, int SrcBytesOffset, int BytesLength)
		{
			int *pd = Dest->Int32Ptr;
			int *ps = Src->Int32Ptr;
			int i = 0;

			for (i = 0; i < BytesLength / 4; i++)
				pd[i] = ps[i];
				//*pd++ = *ps++;


			for (i = 0; i < BytesLength % 4; i++)
				((char *)pd)[i] = ((char *)ps)[i];
				//*(char *)pd++ = *(char *)ps++;
		}

#pragma endregion

		/**<summary>检查对象是否为值类型对象</summary>
		///<remarks></remarks>
		///<param name="value">待检查对象</param>
		///<return>True = ValueType, False = Not ValueType.</return>
		generic<class T>
		static bool IsValueType(T% value)
		{
			return isinst<ValueType^,Object^>((Object^)value);
		}

		/**<summary>检查类型是否为值类型对象</summary>
		///<remarks></remarks>
		///<return>True = ValueType, False = Not ValueType.</return>
		generic<class T>
		static bool IsValueType()
		{
			return (T::typeid)->IsValueType;
		}

		/**<summary>查看对象占用内存大小</summary>
		///<remarks></remarks>
		///<param name="obj">待分析对象</param>
		///<return>对象占用内存大小</return>
		generic<class T>
		static int SizeOf(T% obj)
		{
			if(IsValueType(obj))
			{
				return sizeof(obj);
			}
			else
			{
				return Marshal::SizeOf(obj);
			}
		}

		/**<summary>查看值类型占用内存大小</summary>
		///<remarks></remarks>
		///<return>占用内存大小</return>
		generic<class T>
		where T:System::ValueType
		static int SizeOf()
		{
			return sizeof(T);
		}
	private:
		template < class T, class U > 
		static bool isinst(U u) {
		    return dynamic_cast< T >(u) != nullptr;
			//return safe_cast< T >(u) != nullptr;
		}

	};

#pragma endregion
}

 

内存复制类(MemoryCopy.h):

#pragma once

#pragma unmanaged
private class MemoryCopy
{
public:

	MemoryCopy(void)
	{
	}

	~MemoryCopy(void)
	{
	}


	static void CopyInt(unsigned char *d, unsigned char *s, int l)//4字节复制,适用于32位操作系统
	{
		int *pd = (int *)d;
		int *ps = (int *)s;
		int i = 0;

		for (i = 0; i < l / 4; i++)
			*pd++ = *ps++;

		for (i = 0; i < l % 4; i++)
			*(char *)pd++ = *(char *)ps++;
	}

	static void CopySD(unsigned char *d, unsigned char *s, int l)//用movesd拷贝
	{
		_asm {
			mov esi, s;
			mov edi, d;
			mov edx, l;
			mov ecx, edx;
			shr ecx, 2;
			rep movsd;
			mov ecx, edx;
			and ecx,3;
			rep movsb;
		}
	}

	static void CopyD(unsigned char *d, unsigned char *s, int l)//用movd复制
	{

		_asm{
			mov eax,s;
			mov edx,d;
			mov ecx,l;
			shr ecx,5;
			jz done;

ll:                movd mm0, qword ptr [eax];
			movd mm1, qword ptr [eax+8];
			movd mm2, qword ptr [eax+16];
			movd mm3, qword ptr [eax+24];

			movd qword ptr [edx],mm0;
			movd qword ptr [edx+8], mm1;
			movd qword ptr [edx+16], mm2;
			movd qword ptr [edx+24], mm3;

			add eax,32;
			add edx,32;
			dec ecx;
			jnz ll;
done:

		};
	}

	static void CopyDQU(unsigned char *d, unsigned char *s, int l)//用movdqu复制
	{

		_asm{
			mov eax,s;
			mov edx,d;
			mov ecx,l;
			shr ecx,7;
			jz done;
ll:         
			movdqu xmm0, [eax];
			movdqu xmm1, [eax+16];
			movdqu xmm2, [eax+32];
			movdqu xmm3, [eax+48];


			movdqu [edx],xmm0;
			movdqu [edx+16],xmm1;
			movdqu [edx+32],xmm2;
			movdqu [edx+48],xmm3;

			add eax,64;
			add edx,64
				dec ecx;
			jnz ll;
done:

		};
	}

	static void CopyNTDQ(unsigned char *d, unsigned char *s, int l)//用movntdq复制
	{

		_asm{
			mov esi,s;
			mov edi,d;
			mov ecx,l;
			shr ecx,6;
			jz done;
ll:                

			prefetchnta [esi];
			movdqa xmm0, [esi];
			movdqa xmm1, [esi+16];
			movdqa xmm2, [esi+32];
			movdqa xmm3, [esi+48];

			movntdq [edi],xmm0;
			movntdq [edi+16],xmm1;
			movntdq [edi+32],xmm2;
			movntdq [edi+48],xmm3;


			add esi,64;
			add edi,64
				dec ecx;

			jnz ll;
done:
		};
	}
};
#pragma managed


源码下载地址:http://download.csdn.net/detail/malingxian/3583336

类库下载地址:http://download.csdn.net/detail/malingxian/3583356

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值