zoukankan      html  css  js  c++  java
  • C#-初识IntPtr

    初识IntPtr

    一:什么是IntPtr

    先来看看MSDN上说的:用于表示指针或句柄的平台特定类型。这个其实说出了这样两个事实,IntPtr 可以用来表示指针或句柄、它是一个平台特定类型。
    对于它的解释,这个哥们写的比较好:It's a class that wraps a pointer that is used when calling Windows API functions. The underlying pointer may be 32 bit or 64 bit, depending on the platform.

    二:用在什么地方

    (1)C#调用WIN32 API时

    (2)C#调用C/C++写的DLL时(其实和1相同,只是这个一般是我们在和他人合作开发时经常用到)

    三:怎样用

    例如有一函数原型定义为:DLLDemo_API int __stdcall Inptr_Test (LONG param1, HWND hWnd);那么我们在C#中引用时就要这样写:

     [DllImport("DllPlayer.dll", EntryPoint = "IP_TPS_OpenStream")]
     public static extern int  Inptr_Test (int param1, IntPtr hWnd);

    在调用的时候就可以向Inptr_Test 的第二个参数传入某一控件的Handle。这里涉及到C#类型与C++类型的对应关系,网上这种有很多,这里就不再赘述,只谈几个经常用到的和经常出错的。

          (1)一般对于char* ,void*这种可以直接对应IntPtr,比如在C#中,我们经常用string类型,其转换为IntPtr再传给char*,void*等,转换方法为

    string txt="test"; Marshal.StringToCoTaskMemAuto(txt);

    这里有时会用StringToCoTaskMemAnsi,不过StringToCoTaskMemAuto自动分配内存就可以了。这样就会将txt的内容复制到非托管的内存块中。

    (2)对于结构体,比如有一结构体 StructText,将其转换为Intptr,尽量不要直接用Marshal.StructureToPtr,这样很容易出错。可以这样来用:

    intsize = Marshal.SizeOf(StructText);//获取结构体占用空间大小

    IntPtrintptr= Marshal.AllocHGlobal(size);//声明一个同样大小的空间

    Marshal.StructureToPtr(StructText, intptr, true);//将结构体放到这个空间中

    (3) 通过IntPtr访问内存

    byte* bytes = (byte*)intPtr.ToPointer(); 直接转换成类型指针(但前提是要允许使用不安全代码 unsafe code)

      for (int index = 0; index < size; index++) 

         Console.Write(*(bytes + index) + ","); 
    }

            Byte[] aray = new Byte[data_size];

     for(int i=0;i<data_size;i++)
              {
                   aray[i] = Marshal.ReadByte(p_data, i);
              }
            

           //Marshal.Copy(aray, 0, p_data, data_size);   将数据从托管堆拷贝到非托管堆使用

    (4) 通过IntPtr 释放内存

    Marshal.FreeHGlobal(p_data);

  • 相关阅读:
    微人事项目-mybatis-持久层
    通过外键连接多个表
    springioc
    Redis 消息中间件 ServiceStack.Redis 轻量级
    深度数据对接 链接服务器 数据传输
    sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取
    sqlserver 索引优化 CPU占用过高 执行分析 服务器检查
    sql server 远程备份 bak 删除
    冒泡排序
    多线程 异步 beginInvoke EndInvoke 使用
  • 原文地址:https://www.cnblogs.com/grj001/p/12223334.html
Copyright © 2011-2022 走看看