C# 如何调用 C++ 编写的 DLL_C# 调用 C++ DLL 完整教程

星降
发布: 2025-11-25 17:04:36
原创
171人浏览过
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_c# 调用 c++ dll 完整教程

在 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

立即学习C++免费学习笔记(深入)”;

#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] 特性导入非托管函数。注意数据类型映射和字符串处理。

爱图表
爱图表

AI驱动的智能化图表创作平台

爱图表 305
查看详情 爱图表
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;"><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()}");
}
登录后复制

}

关键点说明:

  • CallingConvention.Cdecl: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 Walkerdumpbin /exports 查看 DLL 导出函数名。

以上就是C# 如何调用 C++ 编写的 DLL_C# 调用 C++ DLL 完整教程的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号