C#指针操作Marshal实例

        static void Main(string[] args)
        {
            byte[] a = new byte[]{0,0,0,0};
            byte[] b = new byte[] {1,2,3,4};
            IntPtr pt = Marshal.AllocHGlobal(a.Length);
            //从source数组的startIndex下标开始复制length个对象到ptr;
            Marshal.Copy(b,0,pt+0,b.Length);
            //从ptr复制length个对象到目标数组的,从目标数组的startIndex开始写入。
            Marshal.Copy((pt+1),a,1,2);
            unsafe
            {
                byte* pb = (byte*) pt;
                for (int i = 0; i < a.Length; i++)
                {
                    Console.WriteLine("/b:"+(*pb++) + "/a:" + a[i]);
                }
            }
            //释放非托管内存;
            Marshal.FreeHGlobal(pt);

            byte[] arBt = new byte[]{200,0,20,30,40,50,60,70,80,90,11,12,13,14,0x0f,199};
            IntPtr ptr = Marshal.AllocHGlobal(arBt.Length);
            //写入数据;
            Marshal.Copy(arBt, 0, ptr, arBt.Length);
            short[] arSt = new short[arBt.Length / sizeof(short)];
            int[] arInt = new int[arBt.Length / sizeof(int)];
            //复制为short数据;
            Marshal.Copy(ptr, arSt, 0, arSt.Length);
            //调整数据 此时arSt不变 下面的arInt改变;
            Marshal.WriteByte(ptr, 1, 9);
            Marshal.WriteByte(ptr, 10, (byte)(Marshal.ReadByte(ptr,10)*9));
            //复制为int数据;
            Marshal.Copy(ptr, arInt, 0, arInt.Length);
            for (int i = 0; i < arBt.Length; i++)
            {
                Console.Write(arBt[i] + "-");
            }
            Console.WriteLine();
            for (int i = 0; i < arBt.Length; i++)
            {
                Console.Write(Marshal.ReadByte(ptr,i) + "-");
            }
            Console.WriteLine();
            unsafe
            {  //获取指定数组中指定索引处的元素的地址
                short* ps = (short*)Marshal.UnsafeAddrOfPinnedArrayElement(arSt, 0);
                byte[] tmp0 = BitConverter.GetBytes(*ps);
                Console.WriteLine(*ps+ "/" + (ushort)*ps+ ",byte>>>&0=" + tmp0[0] + ",&1=" + tmp0[1]);
          //获取指定数组中指定索引处的元素的地址
                int* pi = (int*)Marshal.UnsafeAddrOfPinnedArrayElement(arInt, 0);
                byte[] tmp1 = BitConverter.GetBytes(*pi);
                Console.WriteLine(*pi + "/" + (uint)*pi + ",byte>>>&0=" + tmp1[0] + ",&1=" + tmp1[1] +",&2="+ tmp1[2] + ",&3=" + tmp1[3]);

                Console.WriteLine("-----short 2 byte-----");
                for (int i = 0; i < arSt.Length; i++)
                {
                    byte[] tmp = BitConverter.GetBytes(arSt[i]);
                    Console.WriteLine(arSt[i] + "/" + (ushort)arSt[i] + ",byte>>>&0=" + tmp[0] + ",&1=" + tmp[1]);
                }
                Console.WriteLine("-----int 2 byte-----");
                for (int i = 0; i < arInt.Length; i++)
                {
                    byte[] tmp = BitConverter.GetBytes(arInt[i]);
                    Console.WriteLine(arInt[i] + "/" + (uint)arInt[i] + ",byte>>>&0=" + tmp[0] + ",&1=" + tmp[1] + ",&2=" + tmp[2] + ",&3=" + tmp[3]);
                }
            }
            Marshal.FreeHGlobal(ptr);
       unsafe
            {
                Test tt = new Test();
                tt.t1 = 100;
                tt.t2 = true;
                tt.t3 = 6666;
                tt.t4 = 666666;
                tt.t6 = false;
                string s = "ABCD大师0X00";
                char[] chs = s.ToCharArray();
                char* block = stackalloc char[100];
                fixed (char* cpt = chs)
                {
                    for (int i = 0; i < chs.Length; i++)
                    {
                        tt.t5[i] = *(cpt + i);
                        block[i] = *(cpt + i);
                    }
                    Console.WriteLine(new string(tt.t5));
                }
            }
        }
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public unsafe struct Test
        {
            public byte t1;
            public bool t2;
            public ushort t3;
            public int t4;
            //固定大小的缓冲区
            public fixed char t5[100];
            public bool t6;
        }

//----------------------------------

通过上面的例子,我们可以看出,使用C#指针操作内存,非常方便。使用Marshal我们可以获得非托管内存的指针IntPtr。该指针我们可以强制转换为

sbytebyteshortushortintuintlongulongcharfloatdoubledecimalbool的类型指针。之后我们可以Copy,Read ,Write等操作内存。

同C++一样我们获得的指针可以通过指针运算符 *,->,&,++,--进行指定内存的数据和位移操作。也可以通过Marshal,将我们的byte类型数据进行类型转换操作。

Marshal类提供的转换函数功能之强大。

可参阅https://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.marshal_methods%28v=vs.80%29.aspx;

时间: 2024-07-29 00:32:44

C#指针操作Marshal实例的相关文章

Python操作Mysql实例代码教程在线版(查询手册)_python

实例1.取得MYSQL的版本 在windows环境下安装mysql模块用于python开发 MySQL-python Windows下EXE安装文件下载 复制代码 代码如下: # -*- coding: UTF-8 -*- #安装MYSQL DB for pythonimport MySQLdb as mdb con = None try:    #连接mysql的方法:connect('ip','user','password','dbname')    con = mdb.connect('

不借助工具在浏览器中通过Web API执行Dynamics 365操作(Action)实例

摘要: 本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复262或者20170727可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me . 我的上一篇文章 利用Fiddler修改请求信息通过Web API执行Dynamics 365操作(Action)实例 借助了Fiddler工具,你可能会问,如果不借助工具,我只有浏览器可行吗?这就是本文要讲述的. 我们知道一般浏览器按F12会出来开发者工具,我们以Chrome为例来讲解

Selenium2学习-040-JavaScript弹出框(alert、confirm、prompt)操作演示实例

弹出框是网页自动化测试常见得操作页面元素之一,常见的JavaScript弹出框有如下三种: 1.alert(message):方法用于显示带有一条指定消息和一个 OK 按钮的警告框.DemoAlert.html 示例代码如下所示: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html&g

数组与指针(四)——指针操作

// ptr_ops --指针 操作 #include<stdio.h>int main(void){   int urn[5] = {100,200,300,400,500}; int *ptr1,*ptr2,*ptr3; ptr1 = urn;       //把第个地址赋给指针    ptr2 = &urn[2];   //同上 printf("pointer value ,dereferenced pointer ,pointer address:/n");

Day4:T1小技巧(类似于指针操作)T2搜索+小细节

Day4:其中有很多小技巧get T1 一直没有听到过像这样的小技巧的略专业名词,有点类似于指针操作,之前有碰到过很多这样的题目 每次都是以不同的形式出现,但是感觉思想还是有点接近的吧(就比如某天有一题happy,貌似也是这类型的) 这类题目第一眼总是看起来特别的不能写,其实想到了这些技巧之后很简单 感觉这也没有什么规律性或是模板可言 大概的,就是指针思想+平时积累吧 说说这一题吧 在分析正解之前,我们先说一说比较容易想到的骗分方法 设男女人数相同时ans=0,如果下一个是男->ans++,el

memcached—Java操作Memcached实例

前面博客介绍了如何在Windows操作系统中安装Memcached,总结一下如何使用Java操作Memcached实例: 代码一: package com.ghj.packageoftool; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import jav

C 语言中有趣第指针操作(转)

http://blog.csdn.net/ghevinn/article/details/37651149(反汇编题目需要分析) 4.取出内存区域的值 在取某内存地址开始的一个区域的值的时候,取出的值取决于用来取值的类型,譬如int为4个byte,char为1个byte,程序如: void main(){ int a[2] = {261,0}; int *pi = a; char *p = (char*)pi; cout << *(int *)p++ << endl;  //取出p

C#之指针操作

之前听人说C#没有指针,因为不安全,百度了一下是这么说的: 现在因为工作需要操作硬件看门狗,知道原来C#也是可以操作指针的. 程序环境:.NET MicroFramework 开发工具:VisualStudio 2013开发语言:C#通信工具:新生命神码工具 程序功能:我们的开发硬件在特殊外围情况下可能会出新死机现象.解决方法是通过看门狗程序发现死机,然后C#让MCU指针复位.让MCU重启. C#操作单片机指针程序操作如下: 代码: using System; using Microsoft.S

C#中对指针操作报错解决方法

(C#中实际不存在指针,这里是仿C语言中指针操作进行说明) 1.错误1      “指针和固定大小缓冲区只能在不安全的上下文中使用” 解决方法:在方法前加上unsafe关键字 2.错误2 “不安全代码只会在使用 /unsafe 编译的情况下出现” 解决方法:右键选中资源管理器中项目文件--属性--生成--勾选"允许不安全代码复选框"! 事例代码,取变量a的内存地址并输出: using System; using System.Collections.Generic; using Sys