新闻中心

.NET中的P/Invoke是什么?如何调用C++编写的非托管代码?

2025-11-18
浏览次数:
返回列表
使用P/Invoke调用C++非托管代码需四步:1. 用extern "C"导出C++函数防止名称修饰;2. 在C#中用[DllImport]声明对应方法并指定调用约定;3. 正确映射数据类型如int→Int32、char*→StringBuilder;4. 确保DLL与程序架构匹配并置于可访问路径。

.net中的p/invoke是什么?如何调用c++编写的非托管代码?

P/Invoke(Platform Invocation Services)是 .NET 提供的一种机制,允许托管代码调用在非托管动态链接库(如 C++ 编写的 DLL)中定义的函数。当你需要使用操作系统 API 或已有 C/C++ 库时,P/Invoke 是一个常用手段。

如何使用 P/Invoke 调用 C++ 非托管代码

要成功调用非托管代码,需完成以下几个步骤:

1. 确保 C++ 函数以 C 方式导出

.NET 通过函数名查找导出函数,而 C++ 存在函数名修饰(name mangling),因此必须使用 extern "C" 来防止修饰,并确保函数按 C 约定导出。

// MathLibrary.h
#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif
<p>extern "C" MATHLIBRARY_API int Add(int a, int b);</p>

// MathLibrary.cpp
#include "MathLibrary.h"
<p>extern "C" MATHLIBRARY_API int Add(int a, int b) {
return a + b;
}</p>

编译后生成 MathLibrary.dll。

2. 在 C# 中声明外部方法

使用 [DllImport] 特性告诉 .NET 这个方法在非托管 DLL 中定义。需指定 DLL 名称和调用约定。

using System;
using System.Runtime.InteropServices;
<p>class Program {
[DllImport("MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Add(int a, int b);</p><pre class='brush:php;toolbar:false;'>static void Main() {
    int result = Add(5, 3);
    Console.WriteLine("Result: " + result); // 输出: Result: 8
}

}

Whimsical Whimsical

Whimsical推出的AI思维导图工具

Whimsical 182 查看详情 Whimsical

注意: 如果 C++ 导出使用的是 __stdcall,则应改为 CallingConvention.StdCall。上面示例使用 Cdecl,常见于显式导出函数。

3. 处理数据类型映射

托管与非托管类型之间需正确对应。常见映射包括:

  • intInt32
  • doubledouble
  • char*stringStringBuilder
  • boolbool(注意调用约定和大小)

例如,导出一个字符串处理函数:

// C++ 代码
extern "C" MATHLIBRARY_API void GetText(char* buffer, int bufferSize) {
    strncpy_s(buffer, bufferSize, "Hello from C++!", _TRUNCATE);
}

// C# 调用
[DllImport("MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetText(StringBuilder buffer, int bufferSize);
<p>static void Main() {
StringBuilder sb = new StringBuilder(256);
GetText(sb, sb.Capacity);
Console.WriteLine(sb.ToString()); // 输出: Hello from C++!
}</p>

4. 部署与运行

确保生成的 DLL 与 .NET 程序在同一目录下,或位于系统可找到的路径中(如 PATH)。x64 程序需调用 x64 版本的 DLL,x86 同理,注意平台匹配。

可在项目属性中设置“平台目标”,或使用运行时检测并加载对应架构的 DLL。

基本上就这些。只要导出方式正确、签名匹配、类型映射清晰,P/Invoke 能稳定调用大多数 C/C++ 非托管函数。

以上就是.NET中的P/Invoke是什么?如何调用C++编写的非托管代码?的详细内容,更多请关注其它相关文章!


# ai  # 网站seo靠谱易速达  # 线上营销推广方案饭店  # 广元营销推广收费多少  # 潮州专业建网站推广运营  # 网站建设复古设计图  # 沈阳正规网站建设价位表  # 家纺营销推广方案范文  # 岳阳网站建设创意制作  # 沈阳外贸网站推广公司  # 相关文章  # 当你  # 已有  # 如何在  # 扁平化  # 是一个  # 的是  # 什么用  # 不安全  # lsp  # .net  # c#  # c++  # 操作系统  # 高权重企业网站推广 


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


相关推荐: 如何使用 Excel 发布器与 Power BI 分享 Excel 洞察  b站怎么看视频的弹幕数量_b站弹幕数量查看方法  小红书网页版入口链接分享 小红书官网直接进  精准捕获:如何在页面中监听除特定元素外的所有点击事件  Win10快速启动功能利弊分析 Win10开启或关闭快速启动教程【技巧】  双系统安装时,如何设置默认启动系统? msconfig命令了解一下!  荒野行动PC版怎么注册_荒野行动PC版账号注册详细流程图文教程  J*a实现学校排课程序_面向对象结构化项目示例  C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程  sublime怎么预览Markdown渲染效果_Markdown Preview插件 for sublime教程  怎么在html里运行vbs脚本_html中运行vbs脚本方法【教程】  J*a里如何实现订单支付与库存同步功能_支付库存同步项目开发方法说明  126邮箱账号注册 电脑版登录入口  随机参数递归函数的基准调用次数与时间复杂度探究  优化MinIO list_objects_v2 操作的性能瓶颈与最佳实践  Win11怎么查看电脑配置_Win11硬件配置检测工具使用  腾讯QQ邮箱登录入口_QQ邮箱官方网站使用地址  在Socket.IO连接中实现Access Token自动更新与动态重连  微信网页版登录教程_微信网页版登录入口在哪  Win11怎么设置鼠标主按键_Win11鼠标左右键功能互换  解决 Express.js 中 PUT 请求密码修改失败的路由配置指南  C++如何打印当前代码行号与文件名_C++预定义宏FILE与LINE的使用  yandex入口引擎手机版 yandex安卓版下载入口  sublime如何处理大型CSV文件的列对齐_sublime高级表格编辑插件指南  高德地图怎么看全景照片_高德地图全景照片浏览教程  Python getattr() 异常处理深度解析:避免程序意外退出  c++中为什么推荐使用using替代typedef_c++现代化类型别名  微信网页版官方入口直达 微信网页版网页版登录使用方法  漫蛙MANWA漫画主页官方入口 漫蛙漫画最新在线阅读地址  Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突  J*a TimerTask中HashMap意外清空的深层原因与解决方案  qq游戏手机版下载安装_qq游戏移动端入口  FullCalendar 自定义按钮样式定制指南  抖音怎么赚钱_抖音创作者变现方法与途径指南  高德地图公交到站提醒失败如何解决 高德提醒权限设置  J*aScript动态修改指定div内所有a标签样式指南  Promise错误处理:在catch后终止链式then执行的策略  俄罗斯Yandex免登录入口_Yandex搜索引擎官网一键直达  新三国志曹操传110级星符试炼夏侯渊极难攻略  荣耀Play7T运行卡顿解决_荣耀Play7T性能优化  单射、满射与双射的关系 一文理清所有逻辑  护手霜蹭到袖口上了如何清洗? 怎样避免留下一圈油印?  使用Pandas转换并合并DataFrame:多列映射至统一结构  win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法  HTML元素状态管理:根据DIV内容动态启用/禁用按钮  126邮箱网页版官方入口 126邮箱账号在线登录平台  MAC怎么安装Homebrew包管理器_MAC为开发者和高级用户安装命令行工具  Excel文件在线转换快速入口 Excel在线格式转换网站  如何创建没有密码的Windows本地账户_跳过微软账户登录的技巧【教程】  实现分段式页面滚动导航:CSS与J*aScript教程 

搜索