文章目录
- [1 C++ 生成动态库.dll](#1 C++ 生成动态库.dll)
- 2 C#调用C/C++生成动态库.dll
-
- [2.1 [DllImport()] 方式导入 C++动态库.dll](#2.1 [DllImport()] 方式导入 C++动态库.dll)
- [2.2 调用测试](#2.2 调用测试)
- [3 C/C++ 生成通用dll,改进](#3 C/C++ 生成通用dll,改进)
-
- 3.1改进后.h
- [3.2 .cpp](#3.2 .cpp)
- [3.2 C# 调用](# 调用)
- [4 [DllImport()] 方式导入C++生成的 .dll 总结](#4 [DllImport()] 方式导入C++生成的 .dll 总结)
-
- [4.1 指定路径导入](#4.1 指定路径导入)
- [4.2 .dll放在 执行目录下(一定要放对)](#4.2 .dll放在 执行目录下(一定要放对))
C#动态调用DLL文件(有的DLL是用C++或其它语言写的不能直接调用,但可以用态调用)
C#【必备技能篇】VS2019 使用C/C++ 生成DLL 文件,并用 C/C++、C#调用DLL
1 C++ 生成动态库.dll
C++ 生成动态库.dll 详细教程:C++ 生成动态库.dll 及 C++调用DLL,C++ 生成静态库.lib及 C++调用lib
教程中如图,声明了三种类型的函数;
- 导出函数
- 导出类函数
- 以C方式导出函数 注: 只有这种方式才可被 C#调用
下面就用C# 试图调用这三种类型的函数:

2 C#调用C/C++生成动态库.dll
新建 C# windows窗体应用(.NET Framework)
项目
试图通过 引用的方式 引用C/C++生成动态库.dll
,报错,因为这种方式只能 引用C#生成的动态库dll


2.1 [DllImport()] 方式导入 C++动态库.dll
建好 windows窗体应用(.NET Framework)
项目后,
找到
项目中Form1.cs
双击弹出 类似于 MFC的窗口,在右侧拖一个button,


双击进入button函数,写调用 C++动态库.dll中函数的实现代码
- 在button函数外面先导入,C/C++动态库.dll中的函数名
c
//导入函数
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int add(int a, int b);
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll", EntryPoint = "subtract")]
static extern int subtract(int a, int b);
//导入类函数
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll", EntryPoint = "multiply")]
static extern int multiply(int a, int b);
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int divide(int a, int b);
//extern C ,以C方式导入函数
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int Cadd(int a, int b);
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int Csubtract(int a, int b);
2.2 调用测试
在button 函数中,调用函数
c
private void button1_Click(object sender, EventArgs e)
{
//调用函数
//int sum = add(10,5);
int sub = subtract(10,5);
int mul = multiply(10,5);
int div = divide(10, 5);
int Csum = Cadd(10, 5);
int Csub = Csubtract(10, 5);
//显示函数计算结果
//MessageBox.Show("导入函数" + sum.ToString());
//MessageBox.Show("导入函数" + sub.ToString());
//MessageBox.Show("导入类函数" + mul.ToString());
//MessageBox.Show("导入类函数" + div.ToString());
MessageBox.Show("extern C ,以C方式导入函数" + Csum.ToString());
MessageBox.Show("extern C ,以C方式导入函数" + Csub.ToString());
}
完整代码
c
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CdllTest2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//导入函数
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int add(int a, int b);
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll", EntryPoint = "subtract")]
static extern int subtract(int a, int b);
//导入类函数
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll", EntryPoint = "multiply")]
static extern int multiply(int a, int b);
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int divide(int a, int b);
//extern C ,以C方式导入函数
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int Cadd(int a, int b);
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int Csubtract(int a, int b);
private void button1_Click(object sender, EventArgs e)
{
//调用函数
//int sum = add(10,5);
int sub = subtract(10,5);
int mul = multiply(10,5);
int div = divide(10, 5);
int Csum = Cadd(10, 5);
int Csub = Csubtract(10, 5);
//显示函数计算结果
//MessageBox.Show("导入函数" + sum.ToString());
//MessageBox.Show("导入函数" + sub.ToString());
//MessageBox.Show("导入类函数" + mul.ToString());
//MessageBox.Show("导入类函数" + div.ToString());
MessageBox.Show("extern C ,以C方式导入函数" + Csum.ToString());
MessageBox.Show("extern C ,以C方式导入函数" + Csub.ToString());
}
}
}

点击button后,运行报错 ,找不到函数入口点;
导出函数 、 导出类函数 都会报错
"无法在。。。。找到。。函数的入口点
"

extern C ,以C方式导入函数
调用结果 如下
c
int Csum = Cadd(10, 5);
int Csub = Csubtract(10, 5);

3 C/C++ 生成通用dll,改进
为了使自己建的 C/C++ 库可 都可以被C#调用
使用 __cplusplus
,
- 当C++代码时,
__cplusplus
值为1; - 当C 代码时,
__cplusplus
值为0;
c
#ifdef __cplusplus
.
.
.
#endif
3.1改进后.h
c
//#pragma once
#ifndef MATHTEST_H
#define MATHTEST_H
//宏定义导出:
#ifndef MATHTEST_ //如果没有定义 MATHTEST_,就定义MATHTEST_API __declspec(dllexport)
#define MATHTEST_API __declspec(dllexport) //导出
#else
#define MATHTEST_API __declspec(dllimport) //导入
#endif
//动态链接MATHTEST_API库
//以C语言的方式导出函数
//extern "C",告诉编译器这里是C语言代码
#ifdef __cplusplus
extern "C"
{
#endif
MATHTEST_API int Cadd(int a, int b); //加法
MATHTEST_API int Csubtract(int a, int b);//减法
MATHTEST_API int Cmultiply(int a, int b); //乘法
MATHTEST_API int Cdivide(int a, int b); //除法
#ifdef __cplusplus
}
#endif
#endif
当C++ 代码时,__cplusplus
值为1,那么源代码对应部分 等价于
c
extern "C"
{
MATHTEST_API int Cadd(int a, int b); //加法
MATHTEST_API int Csubtract(int a, int b);//减法
MATHTEST_API int Cmultiply(int a, int b); //乘法
MATHTEST_API int Cdivide(int a, int b); //除法
}
#endif
当C 代码时,__cplusplus
值为0,那么源代码 对应部分 等价于;
(#ifdef __cplusplus
...#endif
部分是没有执行的)
c
MATHTEST_API int Cadd(int a, int b); //加法
MATHTEST_API int Csubtract(int a, int b);//减法
MATHTEST_API int Cmultiply(int a, int b); //乘法
MATHTEST_API int Cdivide(int a, int b); //除法
3.2 .cpp
c
#include "mathTest.h"
//加法
int Cadd(int a, int b)
{
return a + b;
}
//减法
int Csubtract(int a, int b)
{
return a - b;
}
//乘法
int Cmultiply(int a, int b)
{
return a * b;
}
//除法
int Cdivide(int a, int b)
{
return a / b;
}
3.2 C# 调用
c
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CdllTest2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//extern C ,以C方式导入函数
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int Cadd(int a, int b);
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll", EntryPoint = "Csubtract")]
static extern int Csubtract(int a, int b);//EntryPoint关键词,要不要都行
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll", EntryPoint = "Cmultiply")]
static extern int Cmultiply(int a, int b);
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int Cdivide(int a, int b);
private void button1_Click(object sender, EventArgs e)
{
//调用函数
int Csum = Cadd(10, 5);
int Csub = Csubtract(10, 5);
int Cmul = Cmultiply(10, 5);
int Cdiv = Cdivide(10, 5);
//显示函数计算结果
MessageBox.Show("extern C ,以C方式导入函数\n"
+ "\nCsum = " + Csum.ToString()
+ "\nCsub = " + Csub.ToString()
+ "\nCmul = " + Cmul.ToString()
+ "\nCdiv = " + Cdiv.ToString());
}
}
}

4 [DllImport()] 方式导入C++生成的 .dll 总结
4.1 指定路径导入
c
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int Cadd(int a, int b);
4.2 .dll放在 执行目录下(一定要放对)
.dll放在 执行目录下bin下面的 Debug或Release下面
c
[DllImport("Dll1.dll")]
static extern int Cadd(int a, int b);

注意,有4种情况:
如果是 Debug X64,那么 .dll就放在 \bin\x64\Debug
下面
如果是 Release X64,那么 .dll就放在 \bin\x64\Release
下面
如果是 Debug Any CPU,那么 .dll就放在 \bin\Debug
下面
如果是 Release Any CPU,那么 .dll就放在 \bin\Release
下面