C# 中的 IntPtr
C# 中的 IntPtr
IntPtr
是 C# 中用于表示指针或句柄的结构,它在处理非托管代码、与 Windows API 交互或管理非托管资源时非常有用。IntPtr
是一个平台无关的类型,能够在 32 位和 64 位系统之间自适应,通常用于存储指针地址或句柄。
特点
- 平台无关性:
IntPtr
在 32 位和 64 位应用程序中能够适应不同的指针大小。 - 操作:提供了多种方法和运算符用于处理指针运算,如加减法等。
- 内存管理:常与
Marshal
类一起使用,用于处理非托管内存的分配和释放。
示例 1: C# 创建 IntPtr
并释放
1. C++ 代码
首先,创建一个简单的 C++ 动态链接库(DLL)。以下是一个名为 MyLibrary.cpp
的 C++ 文件:
// MyLibrary.cpp extern "C" { __declspec(dllexport) void SetValue(int* ptr, int value) { if (ptr) { *ptr = value; // 设置值 } } __declspec(dllexport) int GetValue(int* ptr) { if (ptr) { return *ptr; // 获取值 } return 0; // 指针为空返回 0 } }
编译上面的 C++ 代码为动态链接库 MyLibrary.dll
。
2. C# 代码
接下来,在 C# 项目中调用上面的 C++ 函数。以下是示例代码:
using System; using System.Runtime.InteropServices; class Program { // 导入 C++ 函数 [DllImport("MyLibrary.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void SetValue(IntPtr ptr, int value); [DllImport("MyLibrary.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int GetValue(IntPtr ptr); static void Main(string[] args) { // 分配内存 IntPtr ptr = Marshal.AllocHGlobal(sizeof(int)); try { // 使用 C++ 函数设置值 SetValue(ptr, 42); // 使用 C++ 函数获取值 int value = GetValue(ptr); Console.WriteLine($"Value from C++: {value}"); } finally { // 释放内存 Marshal.FreeHGlobal(ptr); } } }
Demo 2: C++ 创建 IntPtr
并释放
首先,创建一个 C++ 动态链接库(DLL),在其中分配和释放内存。以下是 MyLibrary.cpp
的示例代码:
// MyLibrary.cpp #include <iostream> extern "C" { __declspec(dllexport) int* CreateIntPtr() { // 在 C++ 中创建并分配内存 int* ptr = new int(200); // 分配内存并初始化为 200 return ptr; // 返回指针 } __declspec(dllexport) void ReleaseIntPtr(int* ptr) { // 释放内存 delete ptr; std::cout << "Memory released in C++." << std::endl; } __declspec(dllexport) int GetValue(int* ptr) { // 获取值 return *ptr; } }
C# 调用 C++ Demo
接下来,我们在 C# 中调用 C++ 函数。以下是 C# 代码:
using System; using System.Runtime.InteropServices; class Program { // 导入 C++ 函数 [DllImport("MyLibrary.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr CreateIntPtr(); [DllImport("MyLibrary.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void ReleaseIntPtr(IntPtr ptr); [DllImport("MyLibrary.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int GetValue(IntPtr ptr); static void Main(string[] args) { // 调用 C++ 函数创建 IntPtr IntPtr ptr = CreateIntPtr(); // 从 C++ 中获取值 int value = GetValue(ptr); Console.WriteLine($"Value from C++: {value}"); // 调用 C++ 函数释放 IntPtr ReleaseIntPtr(ptr); } }
总结
这两个示例展示了如何在 C# 和 C++ 中分别创建和释放 IntPtr
。在示例1中,IntPtr
是在托管环境中创建并释放的,而在示例2中,IntPtr
是在非托管环境中创建并释放的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!