C#学习(十一)——IntPtr类型

1.C#中的IntPtr类型被称之为“平台特定的整数类型”,用于本机资源,例如窗口句柄

2.资源的大小取决于使用的硬件和操作系统,即此类型的实例在32位硬件和操作系统中将是32位,在64位硬件和操作系统中将是64位;但其大小总是足以包含系统的指针(因此也可以包含资源的名称)。

3.在调用API函数时,类似含有窗口句柄参数HANDLE)的原型函数,应显示地声明为IntPtr类型

4.IntPtr类型对多线程操作是安全的。
5. int 和IntPtr互转

int i=1; 
IntPtr p=new IntPtr(i);  
int ch_i=(int) p;
  1. IntPtr和string互转
string str="a";
 
IntPtr p=Marshal.StringToHGlobalAnsi(str);
 
string s=Marshal.PtrToStringAnsi(p);
 
Marshal.FreeHGlobal(p);

原文链接:https://blog.csdn.net/weixin_40327927/article/details/99685538

C# IntPtr 与 string互转

一、IntPtr 与 string互转

string str = “aa”;

IntPtr init = Marshal.StringToHGlobalAnsi(str);

string ss= Marshal.PtrToStringAnsi(init);

//最后释放掉

Marshal.FreeHGlobal(init);

二、char*与string互转

string a = “11”;

char* aChar = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(a).ToPointer();

string result = Marshal.PtrToStringAnsi((IntPtr)aChar);

三、char 与 IntPtr互转*

可以直接强制类型转换

IntPtr init = (IntPtr)aChar;

char* aChar = (char*)init;

原文链接:https://blog.csdn.net/jianyoucheng/article/details/12651763

C#中的IntPtr

IntPtr是一个,用于包装调用WindowsAPI函数的指针,根据平台的不同,底层指针可以是32位或64位;它用以表示指针或句柄的平台特定类型,C#中主要用它调用C++\C封装的DLl库;下面主要介绍IntPtr的常见用法

1.int类型与IntPtr类型之间的转换

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace MyIntPtr
{
    class Program
    {
        static void Main(string[] args)
        {
            int nValue1 = 10;
            int nValue2 = 20;
            //AllocHGlobal(int cb):通过使用指定的字节数,从进程的非托管内存中分配内存。
            IntPtr ptr1 = Marshal.AllocHGlobal(sizeof(int));
            IntPtr ptr2 = Marshal.AllocHGlobal(sizeof(int));
            //WriteInt32(IntPtr ptr, int val):将 32 位有符号整数值写入非托管内存。
            //int->IntPtr
            Marshal.WriteInt32(ptr1, nValue1);
            Marshal.WriteInt32(ptr2, nValue2);
            // ReadInt32(IntPtr ptr, int ofs):从非托管内存按给定的偏移量读取一个 32 位带符号整数
            //IntPtr->int
            int nVal1 = Marshal.ReadInt32(ptr1, 0);
            int nVal2 = Marshal.ReadInt32(ptr2, 0);
            //FreeHGlobal(IntPtr hglobal):释放以前从进程的非托管内存中分配的内存。
            Marshal.FreeHGlobal(ptr1);
            Marshal.FreeHGlobal(ptr2);
        }
    }
}

2.string类型与IntPtr之间的转换

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace MyIntPtr
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "aa";
            IntPtr strPtr = Marshal.StringToHGlobalAnsi(str);
            string ss = Marshal.PtrToStringAnsi(strPtr);
            Marshal.FreeHGlobal(strPtr);  
        }
    }
}

3.结构体与IntPtr之间的转换

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace MyIntPtr
{
    class Program
    {
        public struct stuInfo
        {
            public string Name;
            public string Gender;
            public int Age;
            public int Height;
        }
        static void Main(string[] args)
        {
            stuInfo stu = new stuInfo()
            {
                Name = "张三",
                Gender = "男",
                Age = 23,
                Height = 172,
            };

            //获取结构体占用空间的大小
            int nSize = Marshal.SizeOf(stu);
            //声明一个相同大小的内存空间
            IntPtr intPtr = Marshal.AllocHGlobal(nSize);
            //IntPtr->Struct
            Marshal.StructureToPtr(stu, intPtr,true);
            //Struct->IntPtr
            stuInfo Info =(stuInfo)Marshal.PtrToStructure(intPtr, typeof(stuInfo));

            Console.ReadKey();

        }
    }
}
 

转载于:https://www.cnblogs.com/QingYiShouJiuRen/p/10274197.html

intptr_t详解

看leveldb代码时候发现inptr_t居然不知道是啥,搜索了一番发现一个比较官方的解释:

尽管大部分程序员习惯自由使用标准类型, 如 int 和 long, 编写设备驱动需要一些小心来避免类型冲突和模糊的 bug.

这个问题是你不能使用标准类型, 当你需要"一个 2-字节 填充者"或者"一个东西来代表一个4-字节 字串", 因为正常的 C 数据类型在所有体系上不是相同大小. 为展示各种 C 类型的数据大小, datasize 程序已包含在例子文件 misc-progs 目录中, 由 O’ Reilly’s FTP 站点提供. 这是一个程序的样例运行, 在一个 i386 系统上(显示的最后 4 个类型在下一章介绍):

morgana% misc-progs/datasize
arch Size: char short int long ptr long-long u8 u16 u32 u64
i686 1 2 4 4 4 8 1 2 4 8
这个程序可以用来显示长整型和指针在 64-位 平台上的不同大小, 如同在不同 Linux 计算机上运行程序所演示的:

arch Size: char short int long ptr long-long u8 u16 u32 u64
i386 1 2 4 4 4 8 1 2 4 8
alpha 1 2 4 8 8 8 1 2 4 8
armv4l 1 2 4 4 4 8 1 2 4 8
ia64 1 2 4 8 8 8 1 2 4 8
m68k 1 2 4 4 4 8 1 2 4 8
mips 1 2 4 4 4 8 1 2 4 8
ppc 1 2 4 4 4 8 1 2 4 8
sparc 1 2 4 4 4 8 1 2 4 8
sparc64 1 2 4 4 4 8 1 2 4 8
x86_64 1 2 4 8 8 8 1 2 4 8
注意有趣的是 SPARC 64 体系在一个 32-位 用户空间运行, 因此那里指针是 32 位宽, 尽管它们在内核空间是 64 位宽. 这可用加载 kdatasize 模块(在例子文件的 misc-modules 目录里)来验证. 这个模块在加载时使用 printk 来报告大小信息, 并且返回一个错误( 因此没有必要卸载它 ):

kernel: arch Size: char short int long ptr long-long u8 u16 u32 u64
kernel: sparc64 1 2 4 8 8 8 1 2 4 8
尽管在混合不同数据类型时你必须小心, 有时有很好的理由这样做. 一种情况是因为内存存取, 与内核相关时是特殊的. 概念上, 尽管地址是指针, 内存管理常常使用一个无符号的整数类型更好地完成; 内核对待物理内存如同一个大数组, 并且内存地址只是一个数组索引. 进一步地, 一个指针容易解引用; 当直接处理内存存取时, 你几乎从不想以这种方式解引用. 使用一个整数类型避免了这种解引用, 因此避免了 bug. 因此, 内核中通常的内存地址常常是 unsigned long, 利用了指针和长整型一直是相同大小的这个事实, 至少在 Linux 目前支持的所有平台上.
因为其所值的原因, C99 标准定义了 intptr_t 和 uintptr_t 类型给一个可以持有一个指针值的整型变量. 但是, 这些类型几乎没在 2.6 内核中使用.

总而言之就是:intptr_t是为了跨平台,其长度总是所在平台的位数,所以用来存放地址。
参考:http://www.cnblogs.com/Anker/p/3438480.html

/* There is some amount of overlap with <sys/types.h> as known by inet code */
#ifndef __int8_t_defined
# define __int8_t_defined
typedef signed char         int8_t;
typedef short int          int16_t;
typedef int               int32_t;
# if __WORDSIZE == 64
typedef long int          int64_t;
# else
__extension__
typedef long long int        int64_t;
# endif
#endif
 
/* Unsigned.  */
typedef unsigned char         uint8_t;
typedef unsigned short int    uint16_t;
#ifndef __uint32_t_defined
typedef unsigned int          uint32_t;
# define __uint32_t_defined
#endif
#if __WORDSIZE == 64
typedef unsigned long int       uint64_t;
#else
__extension__
typedef unsigned long long int    uint64_t;
#endif
/* Types for `void *' pointers.  */
#if __WORDSIZE == 64
# ifndef __intptr_t_defined
typedef long int               intptr_t;
#  define __intptr_t_defined
# endif
typedef unsigned long int    uintptr_t;
#else
# ifndef __intptr_t_defined
typedef int                    intptr_t;
#  define __intptr_t_defined
# endif
typedef unsigned int        uintptr_t;
#endif

原文链接:https://blog.csdn.net/macchan/article/details/38701811

  • 4
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值