天天看點

Visual C++ 6.0靜态、動态連結庫

1.什麼是靜态連接配接庫,什麼是動态連結庫          靜态連結庫與動态連結庫都是共享代碼的方式,如果采用靜态連結庫,則無論你願不願意,lib 中的指令都全部被直接包含在最終生成的 EXE 檔案中了。但是若使用 DLL,該 DLL 不必被包含在最終 EXE 檔案中,EXE 檔案執行時可以“動态”地引用和解除安裝這個與 EXE 獨立的 DLL 檔案。靜态連結庫和動态連結庫的另外一個差別在于靜态連結庫中不能再包含其他的動态連結庫或者靜态庫,而在動态連結庫中還可以再包含其他的動态或靜态連結庫。靜态連結庫與靜态連結庫調用規則總體比較如下。

對于靜态連結庫(比較簡單): 首先,靜态連結庫的使用需要庫的開發者提供生成庫的.h頭檔案和.lib檔案。

生成庫的.h頭檔案中的聲明格式如下: extern "C" 函數傳回類型 函數名(參數表); 在調用程式的.cpp源代碼檔案中如下:

#include "..\lib.h"

#pragma comment(lib,"..\\debug\\libTest.lib") //指定與靜态庫一起連結

第二,因為靜态連結庫是将全部指令都包含入調用程式生成的EXE檔案中。是以如果用的是靜态連結庫,那麼也就不存在“導出某個函數提供給使用者使用”的情況,要想用就得全要!要不就都别要!:)

對于動态連結庫: 動态連結庫的使用,根據不同的調用方法,需要提供不同的資源:

1. 靜态加載------程式靜态編譯的時候就靜态導入dll,這樣的話就需要提供給庫使用者(C客戶)如下檔案:*.lib檔案和.dll檔案和*.h。其有2個壞處:

    1   程式一開始運作就需要載入整個dll,無法載入程式就不能開始運作;     2   由于載入的是整個dll,需要耗費資源較多

其調用方法如下:

#pragma comment(lib,"..\\debug\\libTest.lib")

  但是這種方式的話可以調用Class method.

2.動态加載-----那麼隻需要提供dll檔案。

是以調用程式若想調用DLL中的某個函數就要以某種形式或方式指明它到底想調用哪一個函數。但是無法調用Class method了。 如果要調用Dll中的function,需要經曆3個步驟: Handle h=LoadLibrary(dllName) --> GetProcAddress(h,functionName) 傳回函數指針,通過函指針調用其function-->FreeLibrary(h) 例如:Another.dll有一個int Add(int x,int y)函數。則完整的調用過程如下: typedef int (* FunPtr)(int,int);//定義函數指針

FunPtr funPtr; Handle h=LoadLibrary("Another.dll");

funPtr=(FunPtr)GetProcAddress(h,"Add");

funPtr(2,3);//2+3; FreeLibrary(h);

2.示例 示例之一: 靜态連結庫的建立過程:

Visual C++ 6.0靜态、動态連結庫

例如:我們建立一個自定義字元串的類CHironString, 隻需要在IDE裡面添加class即可,然後program相應函數體 代碼如下所示: SDLL.h檔案 ------------------------------------------------------------------------ // HironString.h: interface for the CHironString class. // //////////////////////////////////////////////////////////////////////

#if !defined(AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_) #define AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_

#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000

class CHironString  { private:

 char* m_data; public:  char * GetData();  CHironString(CHironString &other);  int Length();    CHironString();  CHironString(char * str);  CHironString& operator=(CHironString &other);  virtual ~CHironString(); };

#endif // !defined(AFX_HIRONSTRING_H__B23C5E5E_0E8B_4030_B057_34A40C934C59__INCLUDED_)

SDLL.CPP如下: -------------------------------------------------------------- // HironString.cpp: implementation of the CHironString class. // //////////////////////////////////////////////////////////////////////

#include "stdafx.h" #include "HironString.h"

////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////

CHironString::CHironString() {  m_data=NULL; }

CHironString::CHironString(char * str) {  int len=strlen(str);  m_data=new char[len+1];  strcpy(m_data,str);

}

CHironString::~CHironString() {  delete m_data; }

int CHironString::Length() {  return strlen(m_data); }

CHironString::CHironString(CHironString &other) {  int len=strlen(other.m_data)+1;  m_data=new char[len];  strcpy(m_data,other.m_data); }

CHironString& CHironString::operator =(CHironString &other) {  if(this==&other)   return *this;  if(m_data!=NULL)   delete[] m_data;  int len=strlen(other.m_data)+1;  m_data=new char[len];  strcpy(m_data,other.m_data);  return *this; }

char * CHironString::GetData() {  return m_data; }

然後,将程式編譯後生成sdll.lib。 客戶調用:将CHironString.h和SDLL.lib釋出給client,那麼用戶端就可以調用我們編寫的靜态連結庫了。

示例之二: 動态連結庫的建立

Visual C++ 6.0靜态、動态連結庫

首先我們必須先注意到DLL内的函數分為兩種: (1)DLL 導出函數,可供應用程式調用; (2)DLL 内部函數,隻能在 DLL 程式使用,應用程式無法調用它們。

我們還是建立一個自定義的字元串處理類CHironString,不同之處其是一個動态連結庫Dll。 動态連結庫的export 需要在在相應的頭檔案中編寫相應的MACRO MyDll.h:自定義了一些類(函數)export 宏(該檔案由IDE自動生成)如下

------------------------------------------------------------------

#ifdef MYDLL_EXPORTS

#define MYDLL_API __declspec(dllexport)

#else

#define MYDLL_API __declspec(dllimport)

#endif

這是導出類的宏定義,将導出類必須加上該宏,才能被導出。

此處的MYDLL_EXPORTS會出現在 project-->settings-->C/C++頁面上的 PreProcessor definition中,這個MACRO表明其要定義一個導出宏

CHironString.h 自定義類頭檔案 ---------------------------------------------------------------- // HironString.h: interface for the CHironString class. // //////////////////////////////////////////////////////////////////////

#if !defined(AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_) #define AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_

#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "MyDll.h"

class MYDLL_API CHironString   //加上MYDLL_API表明此為Export Class { private:

 char* m_data; public:  char * GetData();  CHironString(CHironString &other);  int Length();    CHironString();  CHironString(char * str);  CHironString& operator=(CHironString &other);  virtual ~CHironString();

};

#endif // !defined(AFX_HIRONSTRING_H__518E9EC4_0837_4E45_9516_7D6A70CD3D0F__INCLUDED_)

 CHironString.Cpp ------------------------------------------------------------

// HironString.cpp: implementation of the CHironString class. // //////////////////////////////////////////////////////////////////////

經過compile之後,會生成MyDll.dll和MyDll.lib檔案。

用戶端的調用: 1.如果是靜态加載,那麼需要提供*.lib和*.h,運作時候需提供*.dll

2.如果是動态加載,隻需要提供*.dll即可。

繼續閱讀