C#【必备技能篇】Marshal是什么?怎么用?

news2024/12/24 10:31:53

文章目录

  • 学习来源:MSDN官方文档
  • 一、Marshal是什么?
    • 1、英文释义:
    • 2、在MSDN中的定义:
    • 3、通俗理解:
  • 二、Marshal怎么用?【主要以一些实例来了解】
    • 1、Marshal下的方法_部分截图【C#源码】:
    • 2、一些示例
      • 1)数组(Int64类型)写到非托管内存并读回到托管内存
      • 2)数组(double类型)写到非托管内存并读回到托管内存【有疑问!】
      • 3)WriteIntPtr()+ReadIntPtr()
      • 4)Fields:SystemDefaultCharSize和SystemMaxDBCSCharSize

学习来源:MSDN官方文档

https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal?view=net-7.0

一、Marshal是什么?

1、英文释义:

在这里插入图片描述

2、在MSDN中的定义:

在这里插入图片描述


即: 提供用于分配非托管内存、复制非托管内存块和将托管类型转换为非托管类型的方法集合,以及与非托管代码交互时使用的其他杂项方法

3、通俗理解:

Marshal是一个方法集合,主要应用在C#和非托管代码交互时,主要有如下方法:

  • 分配非托管内存
  • 复制非托管内存块
  • 将托管类型转换为非托管类型
  • 其他方法(与非托管代码交互时)

二、Marshal怎么用?【主要以一些实例来了解】

1、Marshal下的方法_部分截图【C#源码】:

在这里插入图片描述
在这里插入图片描述

2、一些示例

1)数组(Int64类型)写到非托管内存并读回到托管内存

using System;
using System.Runtime.InteropServices;

class Example
{
    static void Main()
    {
        //【01】Test1_数组写到非托管内存并读回到托管内存
        // Create a managed array.
        Int64[] managedArray = { 1, 2, 3, 4 };

        // Initialize unmanaged memory to hold the array.
        int size = Marshal.SizeOf(managedArray[0]) * managedArray.Length;

        IntPtr pnt = Marshal.AllocHGlobal(size);

        try
        {
            // Copy the array to unmanaged memory.
            Marshal.Copy(managedArray, 0, pnt, managedArray.Length);

            // Copy the unmanaged array back to another managed array.

            Int64[] managedArray2 = new Int64[managedArray.Length];

            Marshal.Copy(pnt, managedArray2, 0, managedArray.Length);

            Console.WriteLine("The array was copied to unmanaged memory and back.");


            Console.WriteLine("————————————————");
            Console.WriteLine("The array of unmanaged memory:");

            //【重点】因为一个Int64占用8个字节,所以下边的偏移量为i*8
            for (int i = 0; i < managedArray.Length; i++)
            {
                Console.Write(Marshal.ReadInt64(pnt, i * 8) + " ");
            }
            Console.Write("\r\n");



            Console.WriteLine("————————————————");

            Console.WriteLine("The back array of unmanaged memory:");

            for (int i = 0; i < managedArray2.Length; i++)
            {
                Console.Write(managedArray2[i] + " ");
            }
            Console.Write("\r\n");

            Console.ReadLine();
        }
        finally
        {
            // Free the unmanaged memory.
            Marshal.FreeHGlobal(pnt);
        }
    }
}

运行结果:
在这里插入图片描述

2)数组(double类型)写到非托管内存并读回到托管内存【有疑问!】

using System;
using System.Runtime.InteropServices;

class Example
{
    static void Main()
    {
        //【02】Test2_数组写到非托管内存并读回到托管内存

         //Create a managed array.
        double[] managedArray = { 0.1, 0.2, 0.3, 0.4 };

        // Initialize unmanaged memory to hold the array.
        int size = Marshal.SizeOf(managedArray[0]) * managedArray.Length;

        IntPtr pnt = Marshal.AllocHGlobal(size);

        try
        {
            // Copy the array to unmanaged memory.
            Marshal.Copy(managedArray, 0, pnt, managedArray.Length);

            // Copy the unmanaged array back to another managed array.

            double[] managedArray2 = new double[managedArray.Length];

            Marshal.Copy(pnt, managedArray2, 0, managedArray.Length);

            Console.WriteLine("The array was copied to unmanaged memory and back.");

            Console.WriteLine("————————————————");
            Console.WriteLine("The array of unmanaged memory:");

            //【重点】偏移量为i * Marshal.SizeOf(managedArray[0])
            for (int i = 0; i < managedArray.Length; i++)
            {
                //How to read double???这段代码没有实现想要的效果!
                Console.Write(Marshal.ReadInt64(pnt, i * Marshal.SizeOf(managedArray[0])) + " ");
            }
            Console.Write("\r\n");



            Console.WriteLine("————————————————");

            Console.WriteLine("The back array of unmanaged memory:");

            for (int i = 0; i < managedArray2.Length; i++)
            {
                Console.Write(managedArray2[i] + " ");
            }
            Console.Write("\r\n");

            Console.ReadLine();
        }
        finally
        {
            // Free the unmanaged memory.
            Marshal.FreeHGlobal(pnt);
        }
    }
}

运行结果:
在这里插入图片描述

3)WriteIntPtr()+ReadIntPtr()

主要过程:通过IntPtr分配非托管内存—>写内容到非托管内存中—>从非托管内存中读取内容

Marshal.AllocHGlobal—>Marshal.WriteIntPtr()—>Marshal.ReadIntPtr()

using System;
using System.Runtime.InteropServices;

class Example
{
    static void Main()
    {
        //【03】Test3_WriteIntPtr()+ReadIntPtr()
        ReadWriteIntPtr();
        Console.ReadLine();
    }

    static void ReadWriteIntPtr()
    {
        // Allocate unmanaged memory. 
        int elementSize = Marshal.SizeOf(typeof(IntPtr));
        IntPtr unmanagedArray = Marshal.AllocHGlobal(10 * elementSize);

        // Set the 10 elements of the C-style unmanagedArray
        for (int i = 0; i < 10; i++)
        {
            Marshal.WriteIntPtr(unmanagedArray, i * elementSize, (IntPtr)(i + 1));
        }
        Console.WriteLine("Unmanaged memory written.");

        Console.WriteLine("Reading unmanaged memory:");
        // Print the 10 elements of the C-style unmanagedArray
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine(Marshal.ReadIntPtr(unmanagedArray, i * elementSize));
        }

        Marshal.FreeHGlobal(unmanagedArray);

        Console.WriteLine("Done. Press Enter to continue.");
        Console.ReadLine();
    }
}

运行结果:
在这里插入图片描述

4)Fields:SystemDefaultCharSize和SystemMaxDBCSCharSize

在这里插入图片描述

using System;
using System.Text;
using System.Runtime.InteropServices;

public struct Point
{
    public Int32 x, y;
}

public sealed class App
{
    static void Main()
    {
        // Demonstrate the use of public static fields of the Marshal class.
        Console.WriteLine("SystemDefaultCharSize={0}, SystemMaxDBCSCharSize={1}",
            Marshal.SystemDefaultCharSize, Marshal.SystemMaxDBCSCharSize);

        // Demonstrate the use of the SizeOf method of the Marshal class.
        Console.WriteLine("Number of bytes needed by a Point object: {0}",
            Marshal.SizeOf(typeof(Point)));
        Point p = new Point();
        Console.WriteLine("Number of bytes needed by a Point object: {0}",
            Marshal.SizeOf(p));

        // Demonstrate how to call GlobalAlloc and
        // GlobalFree using the Marshal class.
        IntPtr hglobal = Marshal.AllocHGlobal(100);
        Marshal.FreeHGlobal(hglobal);

        Console.ReadLine();
    }
}

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/75962.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自定义RBAC(3)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; RBAC类型的权限&#xff0c;本质上是一种对资源访问路径的控制&#xff0c;且具有典型的树型层次结构。而树型结构&#xff0c;天然地就有父结点和子结点的关系以…

【HarmonyOS】ArkTS Native开发——使用 system函数创建文件

ArkTS是HamronyOS优选的主力语言&#xff0c;但官方文档指南中对于Native应用开发并没有详细的描述&#xff0c;只有一篇Codelab可以学习&#xff08;简易Native C 示例&#xff08;ArkTS&#xff09; (huawei.com)&#xff09;&#xff0c;本文将在Native应用中使用C/C的syste…

计算机毕业设计ssm+vue基本微信小程序的早茶预定系统 uniapp 小程序

项目介绍 本文介绍了使用微信小程序技术开发早茶预定系统的设计与实现过程,首先对实现该系统的技术进行分析,说明选择Java后台技术和MySQL数据库的必要性,然后对基于微信小程序的早茶预定系统的需求进行分析。并接着对系统进行设计,包括架构设计、功能设计、数据库设计。最后进…

关于商业智能 BI 认知上的误区,你有几个

关于商业智能BI的介绍&#xff0c;网络上有太多的杂音&#xff0c;总而言之会把商业智能BI讲解的貌似很简单&#xff0c;感觉上买了一个工具就可以解决所有的问题&#xff0c;这其实是一个非常大的误区。 商业智能BI - 派可数据商业智能BI可视化分析平台 我这里总结了一下&…

宠物店微信小程序开发步骤_宠物店管理系统用什么做

大多数人对于动物医疗专业知识比较匮乏&#xff0c;再加上宠物医疗费用&#xff0c;日常用品都略高&#xff0c;宠物店/宠物医院的前景&#xff0c;再未来依旧可观。 相比于实体店&#xff0c;线上平台无疑有着更广阔的拓客渠道和销售前景&#xff0c;做宠物店/宠物医院小程序…

如何高效制作数据可视化大屏,大屏高效制作攻略分享,总有一款适合你

做数据可视化大屏可不是一件简单的事情&#xff0c;里面有很多技巧&#xff0c;像布局&#xff0c;配色&#xff0c;图表和素材的选用和搭配等等&#xff0c;里面有很多学问。一时半会也做不出一个大屏&#xff0c;即使你会做也需要一定的时间和精力&#xff0c;在大量的需求下…

ABAP学习笔记之——第十一章:Function ALV

一、Function ALV Function ALV 从名字中可以推出&#xff0c;是由 Function(函数)形式提供&#xff0c;因此开发者只需适当使用以有的功能即可。没有必要创建屏幕也没有必要一一写出代码&#xff0c;因此可认为是生产性比较高的方法。 例&#xff1a; *function ALV GRID和…

【测绘程序设计】——大地坐标与空间直角坐标转换

本文分享了 测绘程序设计——大地坐标(B,L,H)与空间直角坐标(X,Y,Z)转换(C#版与Python版),相关源代码(绝对完整,直接运行)与使用示例如下。 目录 Part.Ⅰ 使用示例Chap.Ⅰ C#版Chap.Ⅱ Python版Part.Ⅱ 代码分析Chap.Ⅰ C#版Chap.Ⅱ Python版Part.Ⅲ 源码下载Part.Ⅰ…

12.9 总结

一.复制带有随机指针的链表 要求结构和val都是一样 这个题目我们可以建立一个map表,把新的链表和旧的链表每个节点都构成一组key-val对应 然后遍历旧链表.找到对应的next值和random值 思路: 方法1:迭代map class Solution { public Node copyRandomList(Node head) { if(hea…

Mysql 8.0.31彻底卸载

我们有时需要将mysql卸载重新安装&#xff0c;然而如果不注意其中的细节&#xff0c;只是使用apt remove mysql-server命令是卸载不干净的&#xff0c;即使使用了apt purge mysql-server命令进行卸载再重新安装的mysql还是会保留着原来的密码。正确的操作方式是下面这样子的。 …

百度智能云发布基于Ampere® Altra®的高能效云服务器GR1实例

2021年&#xff0c;百度公布了2030年碳中和目标以及6条科学实现路径。首要举措便是建设更环保的数据中心。百度自建的数据中心PUE一直处于非常领先的位置。百度一直秉持“科技为更好”的可持续发展理念&#xff0c;依托全栈和领先的人工智能技术和丰富的产业实践&#xff0c;在…

前端项目工程化流程(简陋版)

背景 最近想要自己做开始一个项目&#xff0c;然后发现好像挺久没有出 从 0 开始 一个项目了&#xff0c;对项目的一些工程化方面的流程有点生疏了&#xff0c;感觉就是知道一个大概的流程&#xff0c;很多都要靠搜索引擎来帮忙&#xff0c;我就想整理一下&#xff0c;对于前端…

在node.js中使用​ JsonWebToken模块进行token加密

目录 一、token 1、什么是token 2、作用 二、Express中实现token的方法&#xff1a; 1、使用JWT模块&#xff1a;JsonWebToken 2、token验证的流程 3、Express中实现过程 ​ &#xff08;1&#xff09;安装、导入JsonWebToken模块 ​ &#xff08;2&#xff09;在登录…

stm32f767之PWM

仅作笔记&#xff0c;很多内容参考网友文章。 PWM 输出&#xff0c;是利用定时器的比较输出功能&#xff0c;所以就是配置定时器。 1&#xff0c;选择定时器8 tim1和tim8为高级定时器 一般我们选择内部时钟&#xff0c;也就是由APB 外设时钟提供。根据选择的输出IO口&#x…

手把手教你搭建视频去重系统

#01 背景 如今&#xff0c;短视频平台对各类搬运视频的检测力度和精确度越来越高了。无论是影视号的剪辑&#xff0c;还是从油管搬运&#xff0c;即使做了各类复杂的视频变换&#xff0c;都很容易被检测出来。作者都会收到提醒&#xff0c;严重的甚至被封号。 乔布斯演讲原始视…

您公司的财务流程是世界一流的还是二流的?

您公司的财务流程是世界一流的还是二流的&#xff1f; 组织开始意识到&#xff0c;提高财务和会计流程的有效性和效率不仅是财务部门内部的目标&#xff0c;而且对整个公司的战略目标也意义重大。首席财务官必须扪心自问——我们的财务流程是世界一流的还是二流的&#xff0c;…

Mac安装NDK android-ndk-r25b-darwin.dmg

文章目录废话连片教程片段1. 打开要存放的目录.2. 打开 .app 的包内容配置环境变量 MAC (在终端/cmd/命令行中运行)废话连片 最近在用 xx存图 下载 小蓝鸟、油管 视频, 一开始觉得挺好用的, 直到… 免费下载次数已用完. 就想着自己弄一个下载视频的小工具, 便查询到了 python …

基于JavaWeb的宿舍管理系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

网页设计期末课程大作业:基于HTML+CSS+JavaScript+Bootstrap制作响应式网站信息技术交流博客(7页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

gradle的访问目录和支付宝的注意事项

经过我100多次的测试发现。gradle项目不管是打包 还是不打包。他的访问目录都是 config.class.getResourceAsStream("config.properties") 当前class所在的目录&#xff0c; 而支付宝的sdk。他的访问文件的目录是项目的根目录。 比如 你的项目文件是这个样子。运…