新闻中心
.NET中的P/Invoke是什么?如何调用C++编写的非托管代码?
使用P/Invoke调用C++非托管代码需四步:1. 用extern "C"导出C++函数防止名称修饰;2. 在C#中用[DllImport]声明对应方法并指定调用约定;3. 正确映射数据类型如int→Int32、char*→StringBuilder;4. 确保DLL与程序架构匹配并置于可访问路径。

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 stat
ic 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推出的AI思维导图工具
182
查看详情
注意: 如果 C++ 导出使用的是 __stdcall,则应改为 CallingConvention.StdCall。上面示例使用 Cdecl,常见于显式导出函数。
3. 处理数据类型映射
托管与非托管类型之间需正确对应。常见映射包括:
- int ↔ Int32
- double ↔ double
- char* ↔ string 或 StringBuilder
- bool ↔ bool(注意调用约定和大小)
例如,导出一个字符串处理函数:
// 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教程


2025-11-18
浏览次数:次
返回列表
ic 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
}