1. 程式人生 > 其它 >win32:靜態庫、動態庫的編寫和使用

win32:靜態庫、動態庫的編寫和使用

技術標籤:win32

目錄

0x01 靜態庫

0x02 動態庫


庫:功能的提供,只是提供功能,並不是一個程式

可執行程式的生成:.exe 可執行程式(windows下) .obj 目標程式(linux下) 將多個obj程式連結在一起就是一個exe

  1. 預處理:標頭檔案引入、預處理指令的執行
  2. 預編譯
  3. 編譯 :語法檢查、程式優化、一個.cpp 編譯生成一個 .obj 檔案(機器語言)
  4. 連結:將多個obj連結為一個.exe程式 (也就是將多個cpp合成一個exe程式)

如何使用第三方庫:

第三方庫的cpp檔案已經安裝到了我們本地,我們使用時只需要在程式中引入該第三方庫的標頭檔案,也就說只要引入該第三方庫函式的宣告。如果靜態庫,連結時便會將庫中目標程式和我們生成的目標程式連結在一起生成exe;如果是動態庫,執行時,如果需要用到動態庫中的函式,才會動態連結動態庫的目標程式。

靜態庫lib:

連結時將靜態庫的程式碼載入到程式程式碼中

好處:執行效率高,如果不是需求中必須用動態庫,都用靜態庫

動態庫dll:

執行時,需要用到該動態庫時,動態載入該動態庫的程式碼。

好處:exe檔案小,可以在執行時直接更換動態庫

壞處:執行效率比較低

0x01 靜態庫

C的靜態庫建立:

思路:

建立專案,選擇靜態庫,然後向專案中新增一個.h標頭檔案,新增一個.c檔案(注意不是.cpp)

將這樣兩個檔案編寫完成以後,點生成專案,就會在Debug目錄下生成一個.lib檔案,使用C的靜態庫時,需要匯入該lib檔案。

ClangLib.h


#pragma once //防止標頭檔案重複引入

int cLibAdd(int, int);
int cLibSub(int, int);
void cLibShow(int, int);

如何取消預編譯標頭檔案:

專案-->屬性-->配置屬性-->C/C++-->預編譯標頭檔案-->建立/使用編譯標頭檔案-->不使用預編譯頭

CLangLib.c

#include "CLib.h"
#include <stdio.h>

#pragma once //防止標頭檔案重複引入

int cLibAdd(int a, int b) {
	return a + b;
}
int cLibSub(int a, int b) {
	return a - b;
}
void cLibShow(int a, int b) {
	printf("%d+%d=%d", a, b, cLibAdd(a, b));
	printf("%d-%d=%d", a, b, cLibSub(a, b));
}

C++的靜態庫建立:建立方法與C相同,只不過不要建立c檔案,建立cpp檔案即可

C中使用C的靜態庫:

首先你要找到C靜態庫lib檔案的位置,然後用#pragma comment 引入即可

// CuseCLib.cpp : 此檔案包含 "main" 函式。程式執行將在此處開始並結束。
//
#include <stdio.h>
#pragma comment(lib,"..\\Debug\\CLangLib.lib")
int main()
{
	cLibShow(2, 3);
	while (1);
	return 0;
}

C中使用C++的靜態庫(不能)

C++中使用C++的靜態庫:

不僅需要引入lib檔案,還需要引入標頭檔案 或者函式的宣告


#include "pch.h"
#include <iostream>
#pragma comment(lib,"..\\Debug\\CPPLib.lib")
void cLibShow(int, int);
int main()
{
	cLibShow(2, 3);
	while (1);
	return 0;
}

C++中使用C的靜態庫:

不僅需要引入lib檔案,引入標頭檔案或者函式宣告,還需要宣告lib檔案是C的靜態庫

#include <iostream>
#pragma comment(lib,"..\\Debug\\CLangLib.lib")

extern "C" void cLibShow(int, int);
int main()
{
	cLibShow(2, 3);
	while (1);
	return 0;
}

0x02 動態庫

建立C語言動態庫

CLangDLL.h 注意標頭檔案需要加 _declspec(dllexport)

這樣點生成後才會既生成一個dll ,也生成一個lib

#pragma once //防止標頭檔案重複引入

_declspec(dllexport) int cLibAdd(int, int);
_declspec(dllexport) int cLibSub(int, int);
_declspec(dllexport) void cLibShow(int, int);

CLangDLL.c 的編寫同上

使用時,只需要引入.lib檔案即可

// CuseCDLL.cpp : 此檔案包含 "main" 函式。程式執行將在此處開始並結束。
//

#include <stdio.h>
#pragma comment (lib,"..\\Debug\\CLangDLL.lib")
int main()
{
	cLibShow(100, 99);
	while (1);
	return 0;
}

建立CPP動態庫:

其他部分同C動態庫相同,只不過

CPP檔案使用CPP動態庫時候.cpp檔案中需要宣告函式,並且加上 _declspec(dllimport)

CPP動態庫還可以提供一個類出去,在DLL專案中直接新增一個類檔案即可(本質上還是一個.h)

#pragma once
#include <stdio.h>
class _declspec(dllexport) ClassDLL
{
public:
	void add(int, int);
};

#include "ClassDLL.h"



void ClassDLL::add(int a,int b) {
	printf("%d", a + b);
}

使用動態庫中的類

#include <iostream>

#include "../CPPDLL/ClassDLL.h"; //需要引入類的標頭檔案
#pragma comment (lib,"..\\Debug\\CPPDLL.lib") //引入類的動態庫對應的靜態庫

int main()
{
	ClassDLL c1;
	c1.add(11, 22);
	return 0;
}