機械学習基礎理論独習

誤りがあればご指摘いただけると幸いです。数式が整うまで少し時間かかります。リンクフリーです。

勉強ログです。リンクフリーです
目次へ戻る

【VS2022】DLL の作成方法及びデバッグ方法【C++】

DLLの基礎知識

DLL はアプリケーションに呼び出されるプログラムの事で、リンク時には .lib ファイルが必要です。
デバッグ時には .pdb ファイルが必要です。

OpenCVのDLLを見てみる

参考のために OpenCV の DLL を見てみましょう。
opencv\build\x64\vc16\bin に opencv_world4120d.dll, opencv_world4120.dll があり、
opencv\build\x64\vc16\blib に opencv_world4120d.lib, opencv_world4120.lib があります。

d がついているファイルは Debug 時に、d がついていないファイルは Release 時に使用します。

DLL の呼び出し方

静的リンクと動的リンクがあります。
後で詳しく書きますが、簡単に説明すると
静的リンクは #pragma comment(lib, "MyDll.lib") またはプロジェクト設定で .lib をリンク するといった方法で DLL にリンクします。
動的リンクは LoadLibrary, GetProcAddress といった API を使用して動的に DLL にリンクします。

サンプルプログラムの構成

以下のような構成でやります。
MyApp(Solution)
L MyApp(Project) - MFC Dialog Base
L MyDll (Project) - DLL
MyApp から MyDll のクラスを呼び出すようにします。

もろもろの設定をやってみる

それではやっていきましょう。
1. MyApp という名前の MFC Application を Dialog Base で作成します。

2. Solution Explorer で Solution を右クリックし ADD > New Project を開きます。
MyDll という名前の Dinamic-Link Library(DLL) を作成します。

3. Solution Explorer で MyDll を右クリックし Properties を開きます。
Configuration を Debug にして
Configuration Properties > General > Target Name を $(ProjectName)d にします。

4. Solution Explorer で MyDll を右クリックし Add > Classを開きます。
Class name を MyClass にして作成します。(.h, .cpp は勝手に同じ名前になります)
※画像が MyApp になっていたので画像編集ソフトで MyDll と直しました。

5. MyDll の MyClass.h, MyClass.cpp を以下のように書きます。
MyClass.h のソース

#pragma once

#ifdef MYLIBRARY_EXPORTS
#define MYLIBRARY_API __declspec(dllexport)
#else
#define MYLIBRARY_API __declspec(dllimport)
#endif

class MYLIBRARY_API MyClass {
public:
    MyClass();
    ~MyClass();

    int Increment(int add);

private:
    int result;
};

MyClass.cpp のソース

#include "pch.h"
#include "MyClass.h"

MyClass::MyClass() : result(0) {}

MyClass::~MyClass() {}

int MyClass::Increment(int add) {
    for (int i = 0; i < 100; ++i) {
        result += add;
    }
    return result;
}

6. Solution Explorer で MyDll を右クリックし Properties を開きます。
Configuration を All Configurationsにして
Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions に MYLIBRARY_EXPORTS を定義します。
※画像はDebugになっています。画像が間違えています。
セミコロンで区切ってください。

7. Solution Explorer で MyApp を右クリックし Properties を開きます。
(似たような設定なのでスナップショットは省略します。)
Configuration を All Configurations にして Confuguration Properties > C/C++ > General > Additional Include Directories に MyDll のヘッダーファイルのパスを追加します。
Configuration を All Configurations にして Confuguration Properties > Linker > General > Additional Library Directories に $(SolutionDir)$(Platform)\$(Configuration)\;(MyDlld.lib のあるフォルダ)を追加します。
Configuration を Debug にして Confuguration Properties > Linker > Input > Additional Dependencies に MyDlld.lib を設定します。
Configuration を Release にして Confuguration Properties > Linker > Input > Additional Dependencies に MyDll.lib を設定します。

8. MyAppDlg.cpp の OnInitDialog を以下のように書いてください。

BOOL CMyAppDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	MyClass* pObj = new MyClass();
	pObj->Increment(1);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

Debugger で MyDll を Debug してみる

Rebuild Solution 後、Debug 実行すると、普段通りDebug ができます。
MyDll のソースに Break Point を設定するとそこに止まりますし、Watch で変数の値も閲覧できます。
以上です。お疲れさまでした。

最後に

exe を公開するときは、exe と同じフォルダに dll を同梱するだけで OK です。

目次へ戻る