シリーズ記事ディレクトリ
第 1 章: Visual Studio 2019 ダイナミック リンク ライブラリ DLL の確立
第 2 章: VS ダイナミック リンク ライブラリ DLL のデバッグ
目次
序文
前の章で DLL の確立は完了しましたが、DLL は呼び出されたときにのみ実行されます。この章では、同じソリューション内の C++ プロジェクトを使用して DLL をデバッグするプロセスを記録します。
1. 新しい C++ プロジェクトを作成しますか?
同じソリューション エクスプローラーで、ソリューションを右クリック - [追加] - [新しいプロジェクト] - [空のプロジェクトの追加]
2、DLLをデバッグする
1. 暗黙的呼び出し/静的呼び出し
1.1 ファイル設定
DLL ディレクトリ内の .h ファイルと、DLL のコンパイルによって生成された .lib ファイルを、C++ プロジェクトの .cpp と同じディレクトリにコピーします。
Windows ソフト リンク マッピング ファイルを使用すると、ファイルが生成されるたびにコピーする必要がなくなります。
New-Item -ItemType SymbolicLink -Path 原文件路径 -Target 目标文件路径
1.2 C++ デバッグ コードを作成する
何を変える必要があるのか
- ヘッダー内の 2 つのインポートを変更します。
#include "dedip.h"
#pragma comment(lib, "dedip.lib")
- 外部関数を変更する
extern "C" __declspec(dllimport) bool eyeCloseCheck(BYTE*, int, int, int);
- 呼び出されたときに関数を変更する
cout << eyeCloseCheck(buffer, width, height, VailImgNum) << endl;
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <windows.h>
#include "dedip.h"
#pragma comment(lib, "dedip.lib")
#include <opencv2/dnn/dnn.hpp>
using namespace cv;
using namespace std;
extern "C" __declspec(dllimport) bool eyeCloseCheck(BYTE*, int, int, int);
int main()
{
Mat srcImg = imread("D:/ImgEnglish/redeye_img_test/1.bmp");
int width = srcImg.cols;
int height = srcImg.rows;
//imshow("1", srcImg);
//waitKey(0);
//DLL调试
int length = (int)(srcImg.total() * srcImg.elemSize());
BYTE* buffer = new BYTE[length];
memcpy(buffer, srcImg.data, length * sizeof(BYTE));
int VailImgNum = 1;
cout << eyeCloseCheck(buffer, width, height, VailImgNum) << endl;
//imshow("2", OutImg);
//waitKey(0);
}
1.3 ソリューション起動プロジェクトの変更
プロジェクトを右クリックし、スタートアップ プロジェクトとして設定します。
2. 明示的な呼び出し
呼び出しを表示してサンプルコードを投稿して自分で参照するのは面倒
一般的な考え方は、.h と .lib をコピーする必要はないということです。ソリューションをデバッグまたはリリースする場合、生成されたファイルは 1 つのフォルダーにあります。
#include <stdio.h>
#include <windows.h>
void main(void)
{
typedef int(*MyFunDll)(void);
HMODULE hdll = LoadLibrary("Win32Project1.dll"); //加载dll文件
if (hdll != NULL)
{
MyFunDll MyFunCall = (MyFunDll)GetProcAddress(hdll, "main");//检索要调用函数的地址
if (MyFunCall != NULL)
{
MyFunCall(); //调用接口函数
}
}
FreeLibrary(hdll); //释放dll文件
}
LoadLibrary() 関数を使用して dll ファイルをロードし、次に GetProcAddress() 関数を使用して、呼び出されるインターフェイス関数のアドレスを取得します (上記の例では、MyFunCall を使用してインターフェイス関数のアドレスを保存します)。インターフェイス関数 (MyFunCall); 最後に、FreeLibrary() 関数を通じて dll ファイルを解放します。したがって、他の DLL ファイルをロードするために使用される場合、上記の例の変更は次のようになります。
ロードされた DLL ファイルの名前 (上記の例では「Win32Project1.dll」)、
取得するインターフェイス関数の名前 (上記の例では「main」)、
呼び出されるインターフェイス関数の形式 (例:上記の例では、MyFunCall() 関数のパラメータ情報は、呼び出されるインターフェイス関数 "main" と一致している必要があります。
要約する
概要: コードを暗黙的に記述する方が便利ですが、変更があった場合にはファイルを再度コピーする必要があります。
参考: https://blog.csdn.net/weixin_44536482/article/details/91519413
C++ でダイナミック リンク ライブラリ DLL を作成し、DLL を呼び出す - Baidu エクスペリエンス (baidu.com)