C# Marshal类基本概念和入门实例讲解
作者:bcbobo21cn
这篇文章主要介绍了C# Marshal类基本概念和入门实例,具有很好的参考价值,希望对大家有所帮助。
C# Marshal类基本概念及入门
marshal
:直译为“编排”, 在计算机中特 指将数据按某种描述格式编排出来,通常来说一般是从非文本格式到文本格式的数据转化。unmarshal
是指marshal的逆过程。比如在WebService中,我们需要把java对象以xml方式表示并在网络间传输,把java对象转化成xml片段的过程就是marshal.
微软对C#中Marshal类描述的链接在此;
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal?view=net-5.0
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks, and converting managed to unmanaged types, as well as other miscellaneous methods used when interacting with unmanaged code.
提供一个方法集合,分配非托管内存,拷贝非托管内存块,转换托管和非托管类型,以及一些和非托管代码交互的杂类方法;
这是Marshal类的基本功能;.net一共包含四个Marshal类,每个都有一些方法;
下面来看一个Marshal类基本程序;程序运行结果如下;
代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace marshalDemo1 { public struct Point { public Int32 x, y; } public partial class Form1 : Form { [DllImport("Kernel32", ExactSpelling = true, SetLastError = true)] static extern Boolean CloseHandle(IntPtr h); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { textBox1.Text = Marshal.SystemDefaultCharSize.ToString(); textBox2.Text = Marshal.SystemMaxDBCSCharSize.ToString(); textBox3.Text = Marshal.SizeOf(typeof(Point)).ToString(); Point p = new Point(); textBox4.Text = Marshal.SizeOf(p).ToString(); IntPtr hglobal = Marshal.AllocHGlobal(100); textBox5.Text = hglobal.ToString(); Marshal.FreeHGlobal(hglobal); Boolean f = CloseHandle(new IntPtr(-1)); if (!f) { Console.WriteLine("CloseHandle call failed with an error code of: {0}", Marshal.GetLastWin32Error()); } } } }
C# Marshal.Copy实现非托管指针和数组之间的转换
挑战
VectorFileIO套件里面 读写文件是 IntPtr类型的指针操作。
原始数据是Int32数组(Int[采样点,通道]),要写入文件。
读出文件要转换成反映的物理变量是采集的double波形 (double[通道,采样点])。
写文件
//初始化缓存指针对应的非托管内存 IntPtr IntPtr变量 = Marshal.AllocHGlobal(缓存Byte长度); 采集循环 { //讲采集得到的Int一维数组拷贝到缓存 Marshal.Copy(采集一维数组, 0, IntPtr变量, 数组sample长度); //将缓存写入矢量文件 vectorFile.Write(IntPtr变量, 缓存Byte长度); } //释放缓存 Marshal.FreeHGlobal(IntPtr变量); //关闭文件 vectorFile.Close();
读文件
//初始化缓存指针对应的非托管内存 IntPtr IntPtr变量 = Marshal.AllocHGlobal(缓存Byte长度); 读文件循环 { //矢量文件读入缓存 vectorFile.read(IntPtr变量, 缓存Byte长度); //缓存拷贝入一维数组, 数组长度=缓存Byte长度 /4 (因为4 bytes per int32) Marshal.Copy(IntPtr变量, 一维数组, 0, 数组sample长度); //由Int32 一维数组 转换为2维 double数组使用 } //释放缓存 Marshal.FreeHGlobal(IntPtr变量); //关闭文件 vectorFile.Close();
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。