VC++動態鏈接庫

函數庫:把函數組織起來,供其他程序調用,達到函數的複用的目的。
1、靜態函數庫與動態函數庫:
靜態函數庫 - 編譯時代碼直接被編譯鏈接到exe中。
缺點:會使程序的體積非常龐大。不利於模塊的共享。
優點:不會產生dll文件,不依賴dll文件就能運行。

動態函數庫 - 就是把函數或業務代碼封裝在dll文件中。
優點:函數代碼在dll文件中,其他程序可以調用dll中的代碼,可以被多個程序共享。
缺點:生成的exe文件依賴dll,容易導致dll hell問題。

建議:哪怕不需要被其他程序共享,在大型工程中建議通過dll的方式來組織函數,
減少單個exe的體積並且有利於開發人員的分工合作。

2、編寫dll。
打開vc++ 6.0 在工程中選擇 win32 dynamic link library。
在想要被外部函數調用的前加上extern “c” __declspec(dllexport) 或 __declspec(dllimport) int add(int a, int b);
這樣才能被其他程序通過dll的方式調用。
示例代碼如下:

#include <windows.h>
#include <stdio.h>

__declspec(dllexport) int add(int a, int b)
{
    return a + b;
}

__declspec(dllexport) int sub(int a, int b)
{
    return a - b;
}

BOOL APIENTRY DllMain(
        HANDLE hModule,
        DWORD ul_reason_for_call,
        LPVOID lpReserved
)
{
    if(ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        printf("dll is loaded!");
    }
}

3、調用。
a、靜態鏈接:把dll和lib複製到需要調用dll的工程目錄下。
#pragma comment(lib, “lib庫名”)
用extern “c” __declspec(dllexport) int add(int a, int b);
__declspec(dllimport) int add(int a, int b);
然後就可以像調用普通函數一樣調用了。

示例代碼如下:

#include<stdio.h>
#pragma comment(lib, "dllDemo.lib")

__declspec(dllimport) int add(int a, int b);
__declspec(dllimport) int sub(int a, int b);

int main(void)
{
    int a = 10, b = 5;
    printf("a + b = %d\n", add(a, b));
    printf("a - b = %d\n", sub(a, b));
    return 0;
}

b、動態鏈接。
–>聲明一個函數指針:
typedef int (__cdecl* fpAdd)(int, int);
–>聲明一個HMODULE hModule;用來保存加載dll文件的句柄
再用函數指針聲明一個變量,如:fpAdd add;

hModule = LoadLibrary("1.dll");//可以是絕對路徑也可以是相對路徑
if(hModule == NULL)
{
    //error
}
add = (fpAdd)GetProcAddress(hModule, "add");
if(NULL == add)
{
    //error
}
int r = add(1, 2);
FreeLibrary(hModule); //釋放句柄 

示例代碼如下:

# include <windows.h>
# include <stdio.h>
# include <stdlib.h>

typedef int (*fun)(int , int);

int main(void)
{
    int a = 10, b = 5;
    HINSTANCE dllDemo = LoadLibrary("dllDemo.dll");
    fun add, sub;
    if (dllDemo)
    {
        add = (fun)GetProcAddress(dllDemo, "add");
        sub = (fun)GetProcAddress(dllDemo, "sub");
    }
    else
    {
        printf("Fail to load dll\n");
        system("pause");
        exit(1);
    }
    printf("a + b = %d\n", add(a, b));
    printf("a - b = %d\n", sub(a, b));
    system("pause");
    return 0;
}

靜態鏈接與動態鏈接的區別:
靜態鏈接庫在程序啓動的時候就會去檢查dll釋放存在,如果不存在在啓動的時候
就會報錯,程序無法啓動;動態鏈接庫時在運行到的時候纔會去檢查dll是否存在
,而且可以由程序員決定在dll不存在的時候判斷邏輯。

要區分靜態庫、動態庫。dll靜態調用和動態調用:
dll靜態調用和動態調用是動態庫的兩種調用方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章