文章目录
- 1 C++ 生成动态库.dll
- 2 C#调用C/C++生成动态库.dll
- 2.1 [DllImport()] 方式导入 C++动态库.dll
- 2.2 调用测试
- 3 C/C++ 生成通用dll,改进
- 3.1改进后.h
- 3.2 .cpp
- 3.2 C# 调用
- 4 [DllImport()] 方式导入C++生成的 .dll 总结
- 4.1 指定路径导入
- 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中的函数名
//导入函数[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 函数中,调用函数
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());}
完整代码
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方式导入函数
调用结果 如下
int Csum = Cadd(10, 5);int Csub = Csubtract(10, 5);
3 C/C++ 生成通用dll,改进
为了使自己建的 C/C++ 库可 都可以被C#调用
使用 __cplusplus
,
- 当C++代码时,
__cplusplus
值为1; - 当C 代码时,
__cplusplus
值为0;
#ifdef __cplusplus
.
.
.
#endif
3.1改进后.h
//#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"
{
#endifMATHTEST_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,那么源代码对应部分 等价于
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
部分是没有执行的)
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
#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# 调用
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 指定路径导入
[DllImport(@"E:\C#\CdllTest2\CdllTest2\bin\Debug\Dll1.dll")]
static extern int Cadd(int a, int b);
4.2 .dll放在 执行目录下(一定要放对)
.dll放在 执行目录下bin下面的 Debug或Release下面
[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
下面