首页 > 编程语言 >C# 中的 IntPtr

C# 中的 IntPtr

时间:2024-11-08 09:09:31浏览次数:1  
标签:IntPtr C# C++ int MyLibrary ptr

C# 中的 IntPtr

IntPtr 是 C# 中用于表示指针或句柄的结构,它在处理非托管代码、与 Windows API 交互或管理非托管资源时非常有用。IntPtr 是一个平台无关的类型,能够在 32 位和 64 位系统之间自适应,通常用于存储指针地址或句柄。

特点

  1. 平台无关性IntPtr 在 32 位和 64 位应用程序中能够适应不同的指针大小。
  2. 操作:提供了多种方法和运算符用于处理指针运算,如加减法等。
  3. 内存管理:常与 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 是在非托管环境中创建并释放的。

标签:IntPtr,C#,C++,int,MyLibrary,ptr
From: https://www.cnblogs.com/dx5800/p/18527754

相关文章

  • 2个月搞定计算机二级C语言——真题(10)解析
    1.前言本篇我们讲解2个月搞定计算机二级C语言——真题102.程序填空题2.1题目要求2.2提供的代码#include<stdio.h>#pragmawarning(disable:4996)doublefun(doublex[],intn){ inti,k=0; doubleavg=0.0,sum=0.0; for(i=0;i<n;i++) avg......
  • PbootCMS增添同tag标签文章数目显示
    修改文件:文件路径:/apps/home/controller/ParserController.php添加代码:在找到的代码段下方添加:php $tags=implode(',',$rs);//把栏目tags串起来$tagsArrSum=array_count_values(explode(',',$tags));//@mk-tags_one_sum把所有tags组成数组并计算每个......
  • Python pickle解压时可能存在安全风险
    Pythonpickle解压时可能存在安全风险https://www.codebonobo.tech/post/15#Python%20pickle%E8%A7%A3%E5%8E%8B%E6%97%B6%E5%8F%AF%E8%83%BD%E5%AD%98%E5%9C%A8%E5%AE%89%E5%85%A8%E9%A3%8E%E9%99%A9  如果解压对像中有重构的reduce操作,pickle.loads时会执行reduce方......
  • 源码开放:WebSocket应用示例
    1WebSocket概述WebSocket是HTML5下一种新的协议(本质上是一个基于TCP的协议),它实现了浏览器与服务器之间的全双工通信,能够节省服务器资源和带宽,达到实时通讯的目的。WebSocket协议通过握手机制,允许客户端和服务器之间建立一个类似TCP的连接,从而方便它们之间的通信。在线......
  • P7984 [USACO21DEC] Tickets P 题解
    题目传送门前置知识线段树优化建图|最短路解法考虑对票建虚点,从\(c_{i}\)向\(i+n\)连一条权值为\(p_{i}\)的边,然后从\(i+n\)向\([a_{i},b_{i}]\)连一条权值为\(0\)的边。建出反图后\(1\toi\)和\(n\toi\)的路径集合会有重复统计的部分,不妨以\(dis_{1,i......
  • dotnet cli publish 命令行发布脚本 bat shell
    dotnetcli发布脚本publish_remote.bat该脚本实现一键主要发布到远程的共享文件夹中@echooff::定义变量SHARE_PATH:共享文件夹,SOURCE_DIR:代码发布的文件夹,TARGET_DIR:目标文件夹(共享文件夹的映射)setPRO_PATH=.\WebAppsetSHARE_PATH=\\pcmesone\Reportset......
  • chrome浏览器network控制台使用和功能介绍
    chrome浏览器network的控制面板主要分为7大板块1、功能区2、筛选区(功能区漏斗需要开启)3、快照区(功能区需要打开屏幕捕获)4、时间轴区(功能区需要开启overview)5、主显示区6、信息汇总区 一、功能区1、红色圆点代表是否开启network的日志功能,如果灰色的,就代......
  • C# 队列的一些并发模拟
    usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Threading;usingSystem.Collections.Concurrent;namespace......
  • C++总结
    目录一、面向对象的三大特性二、引用2.1概念2.2特性三、类与对象3.1概念3.2类的内容3.3对象的创建四、构造函数与析构函数五、封装六、继承6.1概念与基础使用6.2继承权限6.2.1权限修饰符6.2.2继承权限6.3构造函数6.3.1派生类与基类的构造函数关系6.3......
  • 移动Web前端高效开发实战:HTML 5 + CSS 3 + JavaScript + Webpack + React Native + Vu
    书:pan.baidu.com/s/1tIHXj9HmIYojAHqje09DTA?pwd=jqsoHTML5新特性与应用:介绍HTML5的新特性,包括语义化标签、本地存储、设备兼容、连接特性等,并讲解如何在移动Web前端开发中充分利用这些特性提升用户体验。CSS3样式与动画设计:详细讲解CSS3的样式设计和动画效果,包括选择器、盒......