1、Marshal.SizeOf
返回類的非托管大小(以字節為單位)。
using System; using System.Runtime.InteropServices; public struct Point { public int x; public int y; } class Example { static void Main() { // Create a point struct. Point p; p.x = 1; p.y = 1; Console.WriteLine("The value of first point is " + p.x + " and " + p.y + "."); //先獲取p的內存大小 再分配內存 IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(p)); try { //將數據從托管對象封送到非托管內存塊 //p是要封送的數據的托管對象 //pnt是指向非托管內存塊的指針 Marshal.StructureToPtr(p, pnt, false); Point anotherP; //將數據從非托管內存塊封送到托管對象 //pnt是指向非托管內存塊的指針 //第二個參數是將數據復制到其中的對象。 這必須是格式化類的實例。 anotherP = (Point)Marshal.PtrToStructure(pnt, typeof(Point)); Console.WriteLine("The value of new point is " + anotherP.x + " and " + anotherP.y + "."); } finally { // Free the unmanaged memory. Marshal.FreeHGlobal(pnt); //釋放內存 } } }
2、Marshal.AllocHGlobal
從進程的非托管內存中分配內存。
AllocHGlobal(Int32) 通過使用指定的字節數,從進程的非托管內存中分配內存。
AllocHGlobal(IntPtr) 通過使用指向指定字節數的指針,從進程的非托管內存中分配內存。
返回值:指向新分配的內存的指針。 必須使用 FreeHGlobal(IntPtr) 方法釋放該內存。
IntPtr hglobal = Marshal.AllocHGlobal(100); Marshal.FreeHGlobal(hglobal);
3、Marshal.SizeOf和sizeof的區別
https://www.cnblogs.com/jxnclyk/archive/2010/06/09/1754438.html
4、IntPtr 結構:用於表示指針或句柄的平台特定類型。
示例:使用托管指針來反轉數組中的字符
using System; using System.Runtime.InteropServices; class NotTooSafeStringReverse { static public void Main() { string stringA = "I seem to be turned around!"; int copylen = stringA.Length; //將 Unicode 字符串作為 ANSI (單字節) 字符復制到非托管內存。返回IntPtr指向非托管字符串的開頭的對象。 IntPtr sptr = Marshal.StringToHGlobalAnsi(stringA); //分配與非托管字符串占用的字節數相同的字節數 IntPtr dptr = Marshal.AllocHGlobal(copylen + 1); // The unsafe section where byte pointers are used. unsafe { //獲取指向字符串的起始地址和非托管內存塊的非托管指針,並將該字符串的長度小於該字符串的長度添加到 ANSI 字符串的起始地址 //由於非托管字符串指針現在指向字符串的末尾,因此復制操作會將字符串末尾的字符復制到內存塊的開頭 byte *src = (byte *)sptr.ToPointer(); byte *dst = (byte *)dptr.ToPointer(); if (copylen > 0) { src += copylen - 1; //使用循環將字符串中的每個字符復制到非托管內存塊。 while (copylen-- > 0) { *dst++ = *src--; } *dst = 0; } } //將包含復制的 ANSI 字符串的非托管內存塊轉換為托管的Unicode String對象 string stringB = Marshal.PtrToStringAnsi(dptr); Console.WriteLine("Original:\n{0}\n", stringA); Console.WriteLine("Reversed:\n{0}", stringB); //釋放為非托管 ANSI 字符串和非托管內存塊分配的內存 Marshal.FreeHGlobal(dptr); Marshal.FreeHGlobal(sptr); } } //output: // // Original: // I seem to be turned around! // // Reversed: // !dnuora denrut eb ot mees I