新闻中心
C# 如何调用 C++ 编写的 DLL_C# 调用 C++ DLL 完整教程
C#调用C++ DLL需通过P/Invoke并导出C接口。使用extern "C"和__declspec(dllexport)避免名字修饰,C#中用[DllImport]声明函数,指定CallingConvention.Cdecl、CharSet.Ansi及StringBuilder处理字符串。结构体需用[StructLayout(Sequential)]保证内存布局一致。确保DLL位于输出目录且平台匹配(x86/x64),避免入口点找不到或崩溃问题。

在 C# 中调用 C++ 编写的 DLL,核心在于使用 平台调用服务(P/Invoke)。由于 C++ 编译后的函数名会经过修饰(name mangling),且不支持直接导出托管接口,因此不能像调用 C 风格 DLL 那样简单。本文将一步步说明如何从 C++ 创建可被 C# 调用的 DLL,并在 C# 中成功调用。
1. 编写兼容的 C++ DLL(导出 C 接口)
要让 C# 能调用,C++ DLL 必须以 C 语言方式导出函数,避免 C++ 的名字修饰问题。使用 extern "C" 和 __declspec(dllexport) 声明函数。
// MathLibrary.h
extern "C" {
__declspec(dllexport) int Add(int a, int b);
__declspec(dllexport) double Multiply(double x, double y);
__declspec(dllexport) void GetString(char* buffer, int bufferSize);
}
// MathLibrary.cpp
#include "MathLibrary.h"
#include <cstring>
<p>int Add(int a, int b) {
return a + b;
}</p><p>double Multiply(double x, double y) {
return x * y;
}</p><p>void GetString(char<em> buffer, int bufferSize) {
const char</em> str = "Hello from C++!";
strncpy_s(buffer, bufferSize, str, strlen(str));
}
编译为 DLL: 在 Visual Studio 中创建“动态链接库 (DLL)”项目,生成 MathLibrary.dll。
2. 在 C# 中声明并调用 DLL 函数
C# 使用 [DllImport] 特性导入非托管函数。注意数据类型映射和字符串处理。
using System;
using System.Runtime.InteropServices;
<p>class Program
{
// 声明 C++ 导出的函数
[DllImport("MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Add(int a, int b);</p><pre class="brush:php;toolbar:false;">[DllImport("MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern double Multiply(double x, double y);
[DllImport("MathLibrary.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void GetString(StringBuilder buffer, int bufferSize);
static void Main()
{
// 调用整数函数
int result1 = Add(5, 3);
Console.WriteLine($"Add(5, 3) = {result1}");
// 调用浮点函数
double result2 = Multiply(4.5, 2.0);
Console.WriteLine($"Multiply(4.5, 2.0) = {result2}");
// 调用返回字符串的函数
var sb = new StringBuilder(256);
GetString(sb, sb.Capacity);
Console.WriteLine($"String from C++: {sb.ToString()}");
}}
关键点说明:
美图云修
商业级AI影像处理工具
50
查看详情
-
CallingConvention.Cd
ecl:C++ 默认使用 Cdecl 调用约定,必须匹配。 - StringBuilder:用于接收 C++ 写入的字符串缓冲区。
- CharSet = CharSet.Ansi:确保使用 ANSI 字符集而非 Unicode。
- DLL 文件需放在 C# 程序的运行目录下(如 bin\Debug)。
3. 处理复杂类型(结构体传递)
若需传递结构体,需在 C# 中定义内存布局一致的结构,并使用 [StructLayout]。
// C++ 结构体
struct Point {
int x;
int y;
};
<p>extern "C" {
__declspec(dllexport) double DistanceFromOrigin(Point p);
}
// C# 对应结构体
[StructLayout(LayoutKind.Sequential)]
public struct Point
{
public int x;
public int y;
}
<p>[DllImport("MathLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern double DistanceFromOrigin(Point p);
调用方式:
Point pt = new Point { x = 3, y = 4 };
double dist = DistanceFromOrigin(pt);
Console.WriteLine($"Distance: {dist}");
4. 常见问题与解决方案
- 找不到 DLL:确认 DLL 位于输出目录,或使用绝对路径。
- 无法解析入口点:检查函数名是否被 C++ 修饰,确保使用 extern "C" 导出。
- 崩溃或乱码:检查调用约定、字符集、缓冲区大小是否匹配。
- x86/x64 不匹配:C++ DLL 与 C# 程序目标平台必须一致(都选 x64 或都选 x86)。
基本上就这些。只要 C++ 暴露的是 C 风格接口,C# 就能通过 P/Invoke 可靠调用。关键是保持调用约定、数据类型和内存管理的一致性。调试时可用工具如 Dependency Walker 或 dumpbin /exports 查看 DLL 导出函数名。
以上就是C# 如何调用 C++ 编写的 DLL_C# 调用 C++ DLL 完整教程的详细内容,更多请关注其它相关文章!
# 就能
# 广东网站seo
# 银川市网站优化步骤图
# 不会写文章seo
# 咖啡创业营销推广案例
# 如何营销男装店品牌推广
# 眉山联通公司网站建设
# 怎么学习建设网站
# 罗定seo优化
# 鞍山seo系统
# aspnet网站建设
# 并在
# 浮点
# c++
# 放在
# 迭代
# 的是
# 找不到
# 如何使用
# 美图
# 遍历
# lsp
# 常见问题
# ai
# 工具
# c#
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
AO3官网镜像链接 Archive of Our Own同人文在线浏览
理解J*aScript Promise的微任务队列与执行顺序
《噬血代码2》新预告片发布 展示游戏剧情
如何有效阻止外部脚本意外修改内联样式的高度属性
Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略
J*a最大堆Heapify方法修复:索引计算与边界条件深度解析
windows10怎么查看本机ip_windows10命令提示符ipconfig使用
Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】
Go语言中高效处理x-www-form-urlencoded表单数据
写好的html代码怎么运行出来_运行写好的html代码方法【教程】
TikTok国际版网页端快速入口 TikTok全球版短视频浏览教程
html怎么在cmd下运行php文件_cmd运行html中php文件方法【教程】
CSS响应式网页如何实现主次模块比例自适应_flex-grow与flex-shrink调整
格力空气能E5故障代码是什么情况_格力空气能E5代码解析与应对措施
向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程
邮编格式怎么匹配地址_根据邮编格式快速匹配详细地址的技巧
晋江读书网页版在线登录 晋江读书电脑版官网
漫蛙Manwa2官网入口地址分享 漫蛙漫画PC版永久访问通道
漫蛙漫画官方首页 漫蛙2漫画在线阅读入口
谷歌浏览器如何快速清除某个网站的数据_Chrome网站缓存清理方法
字由网在线版登录地址 字由网网页版安全入口
AngularJS $http POST请求数据传递与Go后端接收实践
响应式图片在网页设计中的正确实现方法
AO3官方在线访问地址 Archive of Our Own最新镜像合集
在Socket.IO连接中实现Access Token自动更新与动态重连
Win11怎么开启省电模式_Win11电池节电模式自动开启
Eclipse怎么运行工程_Eclipse工程运行配置说明
J*aScript中向JSON对象添加新属性的正确姿势
Python多线程中正确使用sigwait处理SIGALRM信号
UE5.7引擎表现爆炸优化无敌!5090跑4K稳定60FPS
单射、满射与双射的关系 一文理清所有逻辑
C++如何使用AddressSanitizer(ASan)_C++调试工具中检测内存访问错误的利器
邮政快递单号查询入口 邮政快递物流信息在线查询入口
FullCalendar 自定义按钮样式定制指南
《GTA6》开发画面疑似泄露!这次可不是AI了
J*a实现学校排课程序_面向对象结构化项目示例
J*a里如何实现订单支付与库存同步功能_支付库存同步项目开发方法说明
抖音极速版最新版本 抖音极速版官方下载地址
高德地图公交到站提醒失败如何解决 高德提醒权限设置
C++ explicit关键字防止隐式转换_C++构造函数安全规范
漫蛙MANWA漫画主页官方入口 漫蛙漫画最新在线阅读地址
动漫花园资源网使用步骤_动漫花园资源网下载流程
腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程
俄罗斯Yandex免登录入口_Yandex搜索引擎官网一键直达
PyTorch模型训练准确率不提升:诊断与修复常见指标计算错误
Golang如何使用buffered channel提高性能_Golang buffered channel优化技巧
德邦快递查询平台 德邦快递物流信息查询入口
Composer的 "check-platform-reqs" 命令有什么用_在部署前检查生产环境是否满足Composer依赖需求
深入理解J*aScript Promise异步执行与微任务队列
如何创建独立于主系统的J*a运行环境_隔离式环境搭建策略


2025-11-25
浏览次数:次
返回列表
ecl:C++ 默认使用 Cdecl 调用约定,必须匹配。