静的ライブラリ(lib)と動的ライブラリ(dll)の使用


序文

  静的ライブラリ動的ライブラリは、Windowsソフトウェア開発で非常に一般的に使用されています。優れたソフトウェアアーキテクチャの多くの機能はライブラリの形式です。機能をアップグレードする必要がある場合は、プログラム全体をアップグレードせずにライブラリファイルを直接置き換えることができます。これは保守がより便利です。

  一般的なライブラリファイルには、静的ライブラリと動的ライブラリの2つの形式.lib.dllがあります。

  静的ライブラリがexeファイルに形成されると、すべてがにパッケージ化されます。

  ダイナミックライブラリは、実行中にのみexeにインポートされ、動的にロードおよびアンロードできます。


1つは、関数のオーバーロードの理解です。

  C ++は関数のオーバーロードをサポートしていますが、Cは関数のオーバーロードをサポートしていません。

  Cで同じ名前の関数がコンパイルされた後、関数名は同じになります。VSを例にとると、すべてアンダースコア「_」で始まるため、呼び出すと、どの関数を呼び出すかがわかりません。したがって、Cはオーバーロードをサポートしていません。
  Cdeclはこの種の呼び出しメソッドであり、関数名に装飾を追加せずに、元の関数名を直接検索します。

ここに画像の説明を挿入

  C ++で同じ名前の関数がコンパイルされた後、コンパイラはパラメータタイプやパラメータ番号などの意味を関数名に追加して区別します。つまり、各関数名は異なり、区別できるため、C ++はオーバーロードをサポートします。(C ++の命名規則:名前-マングリング)
  (下の図に示されているパラメーターが異なる同じ名前の各関数は、後でコンパイルされる関数の名前が異なります)
  このstdcallの呼び出しメソッドは、パラメーターやその他の装飾を元の関数に追加します関数名。同じ関数関数を区別するために使用されますが、関数がオーバーロードされると関数本体とパラメーターが異なります。

ここに画像の説明を挿入


2.外部「C」の理解

  前述したC ++関数をコンパイルした後、その名前がパラメータ情報を追加して、再び変更され、その後、それぞれの機能の名称は、コンパイル後に異なっているので、C ++の関数とCの関数は、お互いを呼び出すことはできません、そして、彼らは時に発見されますリンク。関数名が使用できない場合、エラーが報告されますしかし実際には、それは可能であり、特定の処理が実行されたことを示しています。

  これがextern「C」の役割です。

  その役割は、関数名がCで生成されるのと同じ方法で関数名を生成することです。

ここに画像の説明を挿入

  この場合、それぞれのコンパイラが関数名の生成方法を使用しなくても、すべてC標準に従って生成されるため、相互に呼び出すことができます。したがって、ダイナミックライブラリを外部から呼び出す場合は、この変更を行います。通常は必須です


3、静的ライブラリの呼び出し

1.静的ライブラリの生成

(1)静的ライブラリ(lib)を生成します

  最初に静的ライブラリ(Visual C ++)をクリックし、ディレクトリを選択した後、[OK]をクリックします。

ここに画像の説明を挿入
  pch.hとpch.cppだけを残して、他のファイルを削除できます。

ここに画像の説明を挿入

ここに画像の説明を挿入
静的ライブラリ.hプログラム

#ifndef PCH_H
#define PCH_H

#include <iostream>


void Print();
int Add(int a, int b);

#endif //PCH_H

ここに画像の説明を挿入
静的library.cppプログラム

#include "pch.h"

using namespace std;
void Print()
{
    
    
	cout << "I am a smart boy!" << endl;
	cout << "666!" << endl;
	cout << "you are a pretty girl!" << endl;
}

int Add(int a, int b)
{
    
    
	return ((a)+(b));
}

  最後に、[生成]をクリックすると、libファイルが生成されます。

ここに画像の説明を挿入


2.静的ライブラリの呼び出し

  プログラムのインポート、リソースファイルのインポート、コンパイラのインポートの3つの方法があります。

  インポート方法に関係なく、ライブラリのヘッダーファイルインポートする必要があります。この記事では、pch.hファイルを追加する必要があり、その.hのパスもプロジェクトに追加する必要があります-"プロパティ-"C / C ++ディレクトリ-"追加ディレクトリ.hファイルのディレクトリを追加します。

ここに画像の説明を挿入
ここに画像の説明を挿入

  1. プログラムを介してインポートしますパス\ \を使用する必要があります

ここに画像の説明を挿入

#include <iostream>
#include "pch.h"

#pragma comment(lib, "D:\\guoqing.zhang\\StaticLibrary\\StaticLib\\Debug\\StaticLib.lib")

int main()
{
    
    
	Print();
	std::cout << Add(3, 6) << std::endl;
}
  1. リソースファイルのインポート
    ここに画像の説明を挿入
  2. コンパイラのインポート

  プロジェクト-"プロパティ-"リンカー-"静的ライブラリパスを追加するための、一般的な追加のライブラリディレクトリ。

ここに画像の説明を挿入

  プロジェクト-「プロパティ」-「リンカー-」は追加の依存関係を入力します。静的ライブラリの名前を追加する必要があります。

ここに画像の説明を挿入

  どんな種類の追加が完了しても、メイン関数ファイルに「pch.h」を追加し、「デバッグ」をクリックすると、実行結果が表示されます。

ここに画像の説明を挿入


第四に、ダイナミックライブラリの呼び出し

1.ダイナミックライブラリの生成

  [プロジェクト]-[新しいプロジェクト]-[ダイナミックリンクライブラリDLL]をクリックすると、パスを選択した後にプロジェクトを生成できます。1つの.hファイルと1つの.cppファイルのみを残すことができ、他のファイルは削除できます。

ここに画像の説明を挿入

ここに画像の説明を挿入
ダイナミックlibrary.hプログラム

#pragma once

#ifndef DLL_H
#define DLL_H

#define  LIB_API extern "C" __declspec(dllexport)
#include <iostream>

LIB_API void Demo();
LIB_API int Sub(int a, int b);
#endif //PCH_H

ここに画像の説明を挿入
ダイナミックライブラリ.cppプログラム

#include "Dll.h"
#include "pch.h"

LIB_API void Demo()
{
    
    
	Print();
	std::cout << Add(3, 5) << std::endl;
}

LIB_API int Sub(int a, int b)
{
    
    
	return ((a)-(b));
}

  そうです、読んだ後、ダイナミックライブラリが静的ライブラリを呼び出すことができることがわかります。この記事のDllライブラリは、静的ライブラリのヘッダーファイルを追加して、前に生成されたStaticLib.libを呼び出します。

  これは、静的ライブラリと動的ライブラリの違いであります。動的ライブラリには他の静的ライブラリまたは動的ライブラリを含めることができますが、静的ライブラリには他の静的ライブラリまたは動的ライブラリを含めることはできません。

  プログラミング後、[生成]をクリックすると、.dllライブラリが生成されていることがわかります。そのフォルダに入ると、対応する.libファイルが生成されていることがわかります。これはライブラリプログラムではなく、関数名と場所だけです。 dllファイル。.dll関数エンティティを見つけるのに便利です。

ここに画像の説明を挿入
ここに画像の説明を挿入
  下図のようなエラーが発生した場合は、プリコンパイル済みヘッダーに問題があります。プリコンパイル済みヘッダーを使用しないことで、正常にコンパイルを完了できます。(プリコンパイルされたファイルは削除されます。)

ここに画像の説明を挿入
ここに画像の説明を挿入

2.ダイナミックライブラリの呼び出し

暗黙の呼び出し:プロジェクトディレクトリの下にDll.dll、Dll.lib、およびDll.hを配置します。

ここに画像の説明を挿入
  リンカー-「Enterキーを押して依存関係を追加し、Dll.libを選択します。

ここに画像の説明を挿入
  Dll.libをリソースファイルまたは添付ファイルの依存関係に追加してから、「Dll.h」ヘッダーファイルをメイン関数に追加し、ライブラリ内の関数を呼び出して、
ここに画像の説明を挿入
  [デバッグ]をクリックすると、正常に実行できます。
ここに画像の説明を挿入
明示的な呼び出し:.hファイルと.libファイルを追加せずに、dllライブラリを直接インポートし、関数ポインターを介してライブラリ内の関数を呼び出します。具体的なプロセスは次のとおりです

。1。dllライブラリLoadLibrary(ライブラリ名)をインポートします
。2。コンストラクターポインタは、関数のパラメーターとタイプを含め、ライブラリファイル内の関数と一致している必要があります。
3.関数ポインターGetProcAddress(ハンドル、関数名/関数番号);(関数番号:関数が.hで宣言されている順序)を介して関数アドレスを取得します
。4。関数ポインターを使用して関数を呼び出します。

#include <iostream>
#include <Windows.h>
int main()
{
    
    
    std::cout << "Hello World!\n";
	//1、导入dll库
	HMODULE h = LoadLibrary(L"Dll.dll");
	//2、构造函数指针
	typedef int(*PSUM) (int, int);//
	//3、利用函数指针调用函数
	PSUM psum =(PSUM)GetProcAddress(h,"Sub");//利用函数名
	//PSUM psum = (PSUM)GetProcAddress(h, (char*)2);//利用函数序号
	std::cout << psum(11, 22) << std::endl << std::endl;

	typedef void(*PDemp) ();//
	//3、利用函数指针调用函数
	/*PSUM psum =(PSUM)GetProcAddress(h,"sum");*///利用函数名
	PDemp pdemo = (PDemp)GetProcAddress(h, (char*)1);//利用函数序号
	pdemo();

	//4、释放DLL
	FreeLibrary(h);
	return 0;
}

正常に呼び出されました。
ここに画像の説明を挿入

  関数名が見つからず、ダイナミックリンクを完了できないことが判明した場合、形成されたライブラリ内の関数名がリンクされた関数名と一致しない可能性があります。(情報を追加して変更されたものと、変更されていないものがあります。)(下の図のエラー)

GetProcAddress関数  を使用してdll内の関数を取得します。dllにエクスポートされた関数は、extern "C"で修飾する必要があります。そうでない場合、関数アドレスが見つかりません。(その理由は、C ++の名前マングリングが関数名の規則を変更するためです)。
ここに画像の説明を挿入
ここに画像の説明を挿入
コードダウンロードの例

おすすめ

転載: blog.csdn.net/qq_34430371/article/details/111354711