動態鏈接庫dll的 靜態加載 與 動態加載


 
動態鏈接是指在生成可執行文件時不將所有程序用到的函數鏈接到一個文件,因為有許多函數在操作系統帶的dll文件中,當程序運行時直接從操作系統中找。  
而靜態鏈接就是把所有用到的函數全部鏈接到exe文件中。
動態鏈接是只建立一個引用的接口,而真正的代碼和數據存放在另外的可執行模塊中,在運行時再裝入;  
而靜態鏈接是把所有的代碼和數據都復制到本模塊中,運行時就不再需要庫了。
 

靜態鏈接方法:#pragma comment(lib, "test.lib") ,靜態鏈接的時候,載入代碼就會把程序會用到的動態代碼或動態代碼的地址確定下來
靜態庫的鏈接可以使用靜態鏈接,動態鏈接庫也可以使用這種方法鏈接導入庫

動態鏈接方法:LoadLibrary()/GetProcessAddress()和FreeLibrary(),使用這種方式的程序並不在一開始就完成動態鏈接,而是直到真正調用動態庫代碼時,載入程序才計算(被調用的那部分)動態代碼的邏輯地址,然后等到某個時候,程序又需要調用另外某塊動態代碼時,載入程序又去計算這部分代碼的邏輯地址,所以,這種方式使程序初始化時間較短,但運行期間的性能比不上靜態鏈接的程序。

 
1. 生成  靜態鏈接庫 newdll)  win32項目 ->  dll

添加.h文件 
betabinlib.h

#ifndef BETABINLIB_H  
#define BETABINLIB_H  
   
#ifdef NEWDLL_EXPORTS   //自動添加的宏   右鍵工程-屬性-配置屬性-預處理器-..定義  
#define MYDLL_API extern "C" __declspec(dllexport)  
#else  
#define MYDLL_API extern "C" __declspec(dllimport)  
#endif  
   
MYDLL_API int add(int x, int y);  // 必須加前綴  
#endif  

 

添加.cpp文件  betabinlib.cpp

 

#include "stdafx.h"
#include "betabinlib.h"
 
int add(int x, int y)
{
    return x + y;
}

 

編譯生成  .dll 和 .lib (1)dll的靜態加載--將整個dll文件 加載到  .exe文件中
特點:程序較大,占用內存較大,但速度較快(免去 調用函數LOAD
 
#include <stdio.h>
#include "betabinlib.h"
#include <Windows.h>
#pragma comment(lib, "newdll.lib")
 
int main()
{
    printf("2 + 3 = %d \n", add(2, 3));
    return 0;
}

 

#include <stdio.h>  
#include <Windows.h>  
   
int main()  
{  
    HINSTANCE h=LoadLibraryA("newdll.dll");  
    typedef int (* FunPtr)(int a,int b);//定義函數指針  
   
    if(h == NULL)  
    {  
    FreeLibrary(h);  
    printf("load lib error\n");  
    }  
    else  
    {  
        FunPtr funPtr = (FunPtr)GetProcAddress(h,"add");  
        if(funPtr != NULL)  
        {  
            int result = funPtr(3, 3);  
            printf("3 + 3 = %d \n", result);  
        }  
        else  
        {  
            printf("get process error\n");  
            printf("%d",GetLastError());  
        }  
        FreeLibrary(h);  
    }  
   
    return 0;  
}  

 

**************************************

靜態庫鏈接時搜索路徑順序:

1. ld會去找GCC命令中的參數-L
2. 再找gcc的環境變量LIBRARY_PATH
3. 再找內定目錄 /lib /usr/lib /usr/local/lib 這是當初compile gcc時寫在程序內的

動態鏈接時、執行時搜索路徑順序:

1. 編譯目標代碼時指定的動態庫搜索路徑
2. 環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑
3. 配置文件/etc/ld.so.conf中指定的動態庫搜索路徑
4. 默認的動態庫搜索路徑/lib
5. 默認的動態庫搜索路徑/usr/lib

有關環境變量:
LIBRARY_PATH環境變量:指定程序靜態鏈接庫文件搜索路徑
LD_LIBRARY_PATH環境變量:指定程序動態鏈接庫文件搜索路徑

**************************************

Linux下編譯鏈接或運行c/c++程序時可能會遇到找不到頭文件,找不到庫文件的錯誤,簡單總結一下這些錯誤的解決方法

1,找不到頭文件

解決方法一:在編譯時使用 -I 來指定頭文件的路徑,例如把頭文件放在 /home/user/include/ 目錄下,則在編譯時加上 -I /home/user/include/ ,如有多個目錄,可多次使用-I來指定

解決方法二:將頭文件的路徑加入環境變量CPATH中,如 export CPATH=" /home/user/include/",也可以根據情況使用下面的三個環境變量:

C_INCLUDE_PATH 編譯C程序時使用的環境變量,用於查找頭文件。
CPLUS_INCLUDE_PATH 編譯C++程序時使用的環境變量,用於查找頭文件。
OBJC_INCLUDE_PATH 編譯Obj-C程序時使用的環境變量,用於查找頭文件。
CPATH 編譯C/C++/Obj-C程序時使用的環境變量,用於查找頭文件。

2,鏈接時找不到庫文件

解決方法一:在鏈接時使用-L參數來指定庫的路徑,例如把某個自己制作的動態庫放在/home/user/lib/目錄下了,則鏈接程序時加上-L/home/user/lib/,同時可以使用-l來指定庫的名稱,如指定線程庫:-lpthread

解決方法二:把庫文件放入系統的庫文件目錄下,如/lib,/usr/lib等,操作系統運行該程序時會自動到這些目錄下找庫文件

解決方法三:把庫文件所在的目錄加入LIBRARY_PATH環境變量中,如 export LIBRARY_PATH=" /home/user/lib/"

3,運行時找不到動態庫

解決方法一:把庫文件放入系統的庫文件目錄下,如/lib,/usr/lib等

解決方法二:把庫文件所在的目錄加入LD_LIBRARY_PATH環境變量中,如 export LD_LIBRARY_PATH=" /home/user/lib/"

 

原文地址:https://www.cnblogs.com/loanhicks/p/7413996.html

 https://www.cnblogs.com/dirge/p/6443317.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM