文章目錄
- 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
下面