C#中的IntPtr
最近在看公司的一个项目时,发现里面有用到IntPtr这种类型,由于做了一些学习,特记录如下
公司的项目是用C#写的,但是还有很大一部分Legacy的code是用C++写的,所以就涉及到在C#中调用C++编写的dll的问题,这个时候,在C#中,就需要用到IntPtr了
IntPtr = > IntPointer ,它是个结构体,我们在C#中看它的源码定义,就可以看到
可以看到,IntPtr是一个结构体(Struct), 这个结构体IntPtr实现了ISerializable接口 (结构Struct不能继承,但是可以实现接口,可以实现一个或多个接口),它在System命名空间下面
.Net中专门提供了这个结构体IntPtr,用来代表句柄或指针. 我们知道,C#中并没有句柄或者指针的概念,所以IntPtr主要是针对调用C++代码时,来用于代表C++中的句柄或者指针
C#中的IntPtr类型,被称为 “"平台特定的整数类型", 主要用于代表本机的资源,比如本机的窗口或句柄。 它的大小取决于使用的硬件和操作系统, 也就是这个IntPtr类型的实例,如果是在32位的硬件和操作系统上,那它就是32位.. 如果是在64位的硬件和操作系统上,就是64位,但其大小总是足以包含系统的指针(包含资源的名称) . 它的英文解释说的非常好: It's 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.
所以,在C#中调用WindowsAPI函数,或者你的同事写的C++函数时,在函数中如果有类似窗口句柄的参数(HANDLE), 我们在C#中调用该函数时,应该把对应的这种参数声明为IntPtr类型
这里举个例子:
假如我们有个同事用C++写了一个函数
int IntPtr_Test(LONG param1, HWND hwnd) { .......... }
这个函数编译后,会在IntPtrTest.dll里面,那么我们在C#中要调用它,我们在C#中应该这样写代码
[DllImport("IntPtrTest.dll")] public static extern int IntPtr_Test(int param1, IntPtr hwnd) { ....... }
我们可以看到,在C++中,第二个参数是传入的某一个控件的Handle, 但是在C#中就需要使用IntPtr类型来代替它