新闻中心

C#的P/Invoke是什么?如何调用本地Win32 API?

2025-11-20
浏览次数:
返回列表
P/Invoke是C#调用非托管代码的机制,通过DllImport声明外部方法,如调用MessageBox或GetSystemInfo,需注意参数类型映射、结构体布局及字符串编码,推荐使用pinvoke.net等工具辅助开发。

c#的p/invoke是什么?如何调用本地win32 api?

P/Invoke(Platform Invocation Services)是C#中用于调用非托管代码(如Win32 API、C/C++编写的DLL)的一种机制。它允许托管代码与本地系统库进行交互,比如调用Windows操作系统提供的API函数。

小云雀 小云雀

剪映出品的AI视频和图片创作助手

小云雀 1949 查看详情 小云雀

基本原理

当你在C#中使用P/Invoke时,.NET运行时会帮你封送(marshal)参数和返回值,在托管类型和非托管类型之间进行转换。你只需声明一个静态外部方法,并通过DllImport指定目标DLL和函数名。

如何调用Win32 API

以调用MessageBox为例,展示如何使用P/Invoke:

using System;
using System.Runtime.InteropServices;

class Program
{
    // 声明外部方法
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType);

    static void Main()
    {
        MessageBox(IntPtr.Zero, "Hello from C#!", "Greeting", 0);
    }
}
  

说明:
  • DllImport:指定要调用的DLL名称(如user32.dll)
  • CharSet:定义字符串编码方式,Auto会根据平台自动选择ANSI或Unicode版本
  • extern:表示该方法在外部实现
  • 参数类型需匹配Win32 API的定义,例如string会被自动转为LPCWSTR或LPCSTR

常见注意事项

成功调用Win32 API需要注意以下几点:
  • 确保函数名正确,有些API有A(ANSI)和W(Unicode)两个版本,推荐使用CharSet控制
  • 数据类型的映射要准确,例如DWORD对应uint,BOOL对应bool(但需设置[MarshalAs])
  • 复杂结构体需要用StructLayout标记布局方式
  • 涉及指针或缓冲区时,注意内存管理和生命周期
例如,调用GetSystemInfo获取系统信息:
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_INFO
{
    public ushort processorArchitecture;
    private ushort reserved;
    public uint pageSize;
    public IntPtr minimumApplicationAddress;
    public IntPtr maximumApplicationAddress;
    public IntPtr activeProcessorMask;
    public uint numberOfProcessors;
    public uint processorType;
    public uint allocationGranularity;
    public uint processorLevel;
    public uint processorRevision;
}

[DllImport("kernel32.dll")]
static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);

static void Main()
{
    GetSystemInfo(out SYSTEM_INFO sysInfo);
    Console.WriteLine($"处理器数量: {sysInfo.numberOfProcessors}");
}

工具辅助

手动查找API声明比较麻烦,可以借助以下资源:
  • pinvoke.net:社区维护的常用Win32 API C#封装
  • Visual Studio的 IntelliSense 支持部分提示
  • 使用工具如DllExport可反向从C#生成可被调用的DLL
基本上就这些。P/Invoke功能强大,但也容易出错,尤其是类型不匹配或内存问题。建议优先使用.NET内置类库,仅在必要时调用Win32 API。

以上就是C#的P/Invoke是什么?如何调用本地Win32 API?的详细内容,更多请关注其它相关文章!


# 最佳选择  # 营销关键词推广提高搜索引擎排名  # 铜川网站推广sem  # 策划案营销与推广计划  # 江西seo人员  # 海口网站建设哪里便宜  # 鱼台seo推广效果如何  # 零食品牌的推广网站  # seo网络营销课程引流  # seo技术亼仐团  # 石首网站seo优化公司  # 帮你  # 只需  # 你在  # 尤其是  # 迭代  # c#  # 推荐使用  # 如何使用  # 遍历  # .net  # win  # c++  # ai  # 工具  # app  # 编码  # 处理器  # 操作系统  # windows  # word  # p/invoke 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: NVIDIA股价11月重挫12%:下月有望好转 但难回5万亿美元巅峰  J*aScript:在map操作中高效处理空数组  React列表渲染与独立状态管理:避免全局状态影响局部更新  深入理解J*a链表中的IPosition接口与使用  J*aScript中管理异步API调用:确保操作顺序与数据一致性  想当下一个《2077》?《心之眼》Steam评价升至"多半好评"  c++中为什么推荐使用using替代typedef_c++现代化类型别名  58动漫网在线官方网 58动漫网正版动漫入口网址  Go语言中JSON数据解码与字段访问指南  可靠CSGO开箱平台解析 CSGO开箱网合集  126邮箱手机版登录官网2026_126手机邮箱免费入口最新  J*a递归快速排序中静态变量导致数据累积问题的解决方案  Node.js CSV 数据处理:基于字段值条件过滤整条记录的策略  Golang如何使用net/url解析URL_Golang URL解析与处理方法  Win11怎么开启高性能模式_Windows 11电源计划优化设置  Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑  怎么去除衣服上的口红印_生活小妙招教你用酒精轻松擦除  Golang如何使用bytes.Split分割字节切片_Golang bytes切片分割方法  Composer的 archive 命令怎么用_快速打包你的PHP项目及其Composer依赖  手机CPU怎么影响游戏体验_手机CPU对游戏性能的影响分析  C++的std::forward_list怎么用_C++ STL中单向链表容器的特点与应用  c++如何使用Catch2编写单元测试_c++简洁易用的BDD风格测试框架  电脑安装程序提示“错误1722”怎么办_Windows Installer服务问题解决【教程】  CSS子选择器:如何区分并样式化嵌套列表的子层级  J*a应用程序首次运行自动创建文件与目录的最佳实践  KFC套餐升级怎么获取优惠代码_KFC套餐升级活动与优惠代码获取方法  HuggingFaceEmbeddings中向量嵌入维度调整的限制与理解  mc.js游戏直达 mc.js网页免下载版本秒进地址  狙击外星人小游戏开始_狙击外星人小游戏立即开始  在J*a中如何开发在线活动报名与管理系统_活动报名管理项目实战解析  多闪网页版在线观看免费入口_多闪官网访问入口  漫蛙manwa官网登录界面_漫蛙漫画网页版主站入口  快手极速版在线观看 官方网页版登录地址  如何将HTML表格多行数据保存到Google Sheet  解决Flask中Quill编辑器内容提交失败及TypeError的指南  单射、满射与双射的关系 一文理清所有逻辑  poki免费入口快捷访问 poki人气小游戏直接玩站点  如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】  Win10系统怎么查看已安装更新_Win10卸载有问题的更新补丁  提升Kafka消费者健壮性:会话超时处理与消息处理语义  使用Python高效删除Word宏并转换DOCM为DOCX格式  如何高效处理PHP中的Excel数据导入导出?PortPHP/Spreadsheet助你轻松搞定!  千牛数据看板网页版_千牛数据看板网页版访问方法  jQuery Mask 插件中实现电话号码固定前导零的教程  ExcelARRAYTOTEXT函数怎么自定义分隔符输出数组文本_ARRAYTOTEXT实现动态生成SQL语句  支付宝如何设置安全保护_支付宝安全设置的全面教程  解决 Vaadin 8 中大文件音频播放与定位时出现的 IOException  Go语言中Map值调用指针接收器方法的限制与应对  解决J*aScript中重复选择项的确认对话框显示问题  使用 Pandas 高效处理 .dat 文件:字符清理与数据计算 

搜索