【C#】Marshal.SizeOf 方法、Marshal.AllocHGlobal 方法、IntPtr 结构
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
/*******相与枕藉乎舟中,不知东方之既白*******/
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战