新闻中心

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


相关推荐: 理解J*aScript Promise的微任务队列与执行顺序  电脑安装程序提示“错误1722”怎么办_Windows Installer服务问题解决【教程】  AO3最新可访问网址 Archive of Our Own官方在线入口  Web Components中自定义开关组件状态同步的常见陷阱与解决方案  探索高级语言到原生C/C++的转译:挑战与内存管理策略  微信网页版扫码登录入口 微信网页版二维码登录入口  《噬血代码2》新预告片发布 展示游戏剧情  解决深度学习模型训练初期异常高损失与完美验证准确率问题  C++ explicit关键字防止隐式转换_C++构造函数安全规范  J*aScript map 迭代中检测空数组元素的有效方法  Win11如何使用Windows Sandbox Win11沙盒功能开启与使用教程【详解】  C++如何比较两个字符串_C++ string compare函数与操作符对比  J*aScript中向JSON对象添加新属性的正确姿势  抖音从哪里进入网页版_抖音官方入口链接  Word2013如何插入视频和音频媒体_Word2013媒体插入的多媒体支持  Python实现多节点属性重叠度分析教程  AO3同人作品网入口 AO3搜索引擎官网永久地址  msn官网入口地址手机版 msn官方网站手机最新链接  composer的"require-dev"部分是用来做什么的?  J*aScript数据结构转换:将对象数组按类别分组  J*aScript实现单选按钮与关联输入框的联动禁用教程  qq浏览器打开空白页怎么办 qq浏览器启动后显示白屏的解决教程  Pygame教程:解决用户输入与游戏状态更新不同步问题  Golang如何实现容器化日志收集与分析_Golang容器日志收集分析方法  必由学官网快捷入口 必由学网页版在线学习平台  Lar*el头像管理:图片缩放与旧文件删除的最佳实践  UC浏览器官网入口2025最新 UC浏览器网页版正式地址  创客贴用户入口官网登录 创客贴网页版电脑版系统  抖音隐秘迷城小游戏入口_ 抖音冒险解谜小游戏秒玩  iCloud登录入口网页版 苹果iCloud官网登录  sublime如何优雅地处理行尾空格_sublime自动清理多余空白字符配置  荒野行动PC版怎么注册_荒野行动PC版账号注册详细流程图文教程  C++如何实现单例模式_C++设计模式之线程安全的单例写法  58动漫网在线官方网 58动漫网正版动漫入口网址  包子漫画官方网站阅读入口-包子漫画在线漫画官网直达链接  铁路12306官网网页端快速入口 铁路12306官方首页登录教程  React中useState与局部变量:理解组件状态管理与渲染机制  qq音乐在线播放入口_qq音乐电脑版登录链接  Adobe PDF表单中利用J*aScript解析与格式化日期组件的教程  Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突  EMS快递官网app_中国邮政速递物流手机客户端  qq游戏免费畅玩入口_qq游戏电脑版快速启动  MAC怎么安装Homebrew包管理器_MAC为开发者和高级用户安装命令行工具  Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题  自定义Bag-of-Words实现:处理带负号的词汇权重  小米汽车11月交付量突破40000台!雷军:将继续努力  12306怎么选座位选到安静区_12306选座安静区域选择策略  J*a如何使用AtomicInteger控制计数_J*a无锁计数器性能分析  c++20的std::jthread是什么_c++可中断线程与RAII式管理  深入理解J*aScript中的B样条曲线与节点向量生成 

搜索