<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    lib 和 dll 的區別、生成以及使用詳解

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接 lib 和 dll 的區別、生成以及使用詳解

    【目錄】

    lib dll介紹

    生成動態庫

    調用動態庫

    生成靜態庫

    調用靜態庫


    首先介紹一下靜態庫(靜態鏈接庫)、動態庫(動態鏈接庫)的概念,首先兩者都是代碼共享的方式。

    靜態庫在鏈接步驟中,連接器將從庫文件取得所需的代碼,復制到生成的可執行文件中,這種庫稱為靜態庫,其特點是可執行文件中包含了庫代碼的一份完整拷貝;缺點就是被多次使用就會有多份冗余拷貝。即靜態庫中的指令都全部被直接包含在最終生成的 EXE 文件

    了。在vs中新建生成靜態庫的工程,編譯生成成功后,只產生一個.lib文件

    動態庫:動態鏈接庫是一個包含可由多個程序同時使用的代碼和數據的庫,DLL不是可執行文件動態鏈接提供了一種方法,使進程可以調用不屬于其可執行代碼的函數。函數的可執行代碼位于一個 DLL 中,該 DLL 包含一個或多個已被編譯、鏈接并與使用它們的進程分開存儲的函數。在vs中新建生成動態庫的工程,編譯成功后,產生一個.lib文件和一個.dll文件

    那么上述靜態庫和動態庫中的lib有什么區別呢?

    靜態庫中的lib:該LIB包含函數代碼本身(即包括函數的索引,也包括實現),在編譯時直接將代碼加入程序當中

    動態庫中的lib:該LIB包含了函數所在的DLL文件和文件中函數位置的信息(索引),函數實現代碼由運行時加載在進程空間中的DLL提供

    總之,lib是編譯時用到的,dll是運行時用到的。如果要完成源代碼的編譯,只需要lib;如果要使動態鏈接的程序運行起來,只需要dll

    以下例子均在vs2010上測試


    生成和使用動態庫

    生成動態庫

    新建項目--win32項目--填寫項目名--確定--下一步--應用程序類型:選擇dll--附加選項:選擇導出符號--完成

    可以看到生成了一個dllmain.cpp 文件,這是dll應用程序的入口,注意它和普通工程的入口main函數不同,這個文件我們不需要修改。

    在這個動態庫中我們舉例導出一個變量,一個類,一個函數,頭文件dll.h如下:

    復制代碼
     1 //新建生成dll的工程時,vs默認定義了宏DLL_EXPORT,因此,DLL_API 是 __declspec(dllexport),用來導出
     2 //當我們在靜態調用dll時,我們包含該頭文件,由于沒有定義DLL_EXPORT,所以DLL_API是
     3 //__declspec(dllimport),用來導入
     4 #ifdef DLL_EXPORTS
     5 #define DLL_API __declspec(dllexport)
     6 #else
     7 #define DLL_API __declspec(dllimport)
     8 #endif
     9 
    10 // 導出類
    11 class DLL_API Cdll {
    12 public:
    13     Cdll(void);
    14     // TODO: 在此添加您的方法。
    15 };
    16 
    17 //導出變量,變量在.cpp文件中定義
    18 extern DLL_API int ndll;
    19 
    20 //導出函數,加extern "C",是為了保證編譯時生成的函數名不變,這樣動態調用dll時才能
    21 //正確獲取函數的地址
    22 extern "C" DLL_API int fndll(void);
    復制代碼

    dll.cpp 文件如下:

    復制代碼
     1 #include "dll.h"
     2 
     3 
     4 // 這是導出變量的一個示例
     5 DLL_API int ndll=6;
     6 
     7 // 這是導出函數的一個示例。
     8 DLL_API int fndll(void)
     9 {
    10     return 42;
    11 }
    12 
    13 // 這是已導出類的構造函數。
    14 // 有關類定義的信息,請參閱 dll.h
    15 Cdll::Cdll()
    16 {
    17     return;
    18 }
    復制代碼

    調用動態庫

    有兩種方法調用動態庫,一種隱式鏈接,一種顯示鏈接。

    調用動態庫:隱式鏈接

    隱式鏈接 需要.h文件,dll文件,lib文件

    (1)將dll放到工程的工作目錄

    (2)設置項目屬性--vc++目錄--庫目錄為lib所在的路徑

    (3)將lib添加到項目屬性--鏈接器--輸入--附加依賴項(或者直接在源代碼中加入#pragma comment(lib, “**.lib”)

    (4)在源文件中添加.h頭文件

    然后就像平常一樣調用普通函數、類、變量

    調用動態庫:顯示鏈接

    顯示鏈接 只需要.dll文件,但是這種調用方式不能調用dll中的變量或者類(其實可以調用類,但是相當麻煩,有興趣者可參考http://blog.csdn.net/jdcb2001/article/details/1394883

    顯示調用主要使用WIN32 API函數LoadLibrary、GetProcAddress,舉例如下:

    復制代碼
     1 typedef int (*dllfun)(void);//定義指向dll中函數的函數指針
     2     HINSTANCE hlib = LoadLibrary(".\\dll.dll");
     3     if(!hlib)
     4     {
     5         std::cout<<"load dll error\n";
     6         return -1;
     7     }
     8     dllfun fun = (dllfun)GetProcAddress(hlib,"fndll");
     9     if(!fun)
    10     {
    11         std::cout<<"load fun error\n";
    12         return -1;
    13     }
    14     fun();
    復制代碼

    生成和使用靜態庫

    生成靜態庫

    新建項目--win32項目--填寫項目名--確定--下一步--應用程序類型:選擇靜態庫

    靜態庫項目沒有main函數,也沒有像dll項目中的dllmain。

    創建項目后添加.h文件,添加相應的導出函數、變量或類,如下所示

    復制代碼
     1 #ifndef _MYLIB_H_
     2 #define _MYLIB_H_
     3 
     4 void fun(int a);
     5 
     6 extern int k;
     7 
     8 class testclass
     9 {
    10 public:
    11     testclass();
    12     void print();
    13 };
    14 
    15 #endif
    復制代碼

    .cpp文件如下

    復制代碼
     1 #include "stdafx.h"
     2 #include "lib.h"
     3 #include <iostream>
     4 
     5 void fun(int a)
     6 {
     7     std::cout<<a<<"lib gen\n";
     8 }
     9 
    10 int k = 222;
    11 
    12 testclass::testclass()
    13 {
    14     std::cout<<"123\n";
    15 }
    16 
    17 void testclass::print()
    18 {
    19     std::cout<<"this is testcalss\n";
    20 }
    復制代碼

    編譯工程后就會生成一個.lib文件

    使用靜態庫

    需要.h文件,lib文件

    (1)設置項目屬性--vc++目錄--庫目錄為lib所在的路徑

    (2)將lib添加到項目屬性--鏈接器--輸入--附加依賴項(或者直接在源代碼中加入#pragma comment(lib, “**.lib”))

    (3)在源文件中添加.h頭文件

    然后就像平常一樣調用普通函數、類、變量,舉例如下:

    復制代碼
     1 #include <iostream>
     2 #include "lib.h"
     3 
     4 #pragma comment(lib, "lib.lib")
     5 
     6 int main()
     7 {
     8     fun(4);
     9     std::cout<<k<<std::endl;
    10     testclass tc; 
    11     tc.print();
    12     return 0;
    13 }
    復制代碼RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全