Linux下C 動態庫的生成和使用

2021-06-19 03:12:14 字數 3999 閱讀 4287

1. 匯出函式的動態庫

#ifndef _dlltest_h

#define _dlltest_h

extern "c" int add(int a,int b);

typedef int (*add_t)(int a,int b);

#endif

#include "dlltest.h"

int add(int a,int b)

上述動態庫需要匯出函式add。編譯生成動態庫:g++ -fpic -shared -o libdlltest.so dlltest.cc

動態庫載入方式分為靜態和動態載入。

靜態方式載入動態庫示例:

#include using namespace std;

#include "dlltest.h"

int main(int argc,char** argv)

編譯可執行程式:g++ -o main main.cc  -ldlltest -l. /

動態方式載入動態庫示例:

#include using namespace std;

#include #include "dlltest.h"

int main(int argc,char** argv)

add_t fn = (add_t)dlsym(so_handle, "add"); // 載入函式

if (null == fn)

cout << "add 57 + 3 = " << fn(57, 3) << endl; // 呼叫函式

dlclose(so_handle); // 關閉so控制代碼

}

編譯可執行程式:g++ -o main main.cc -ldl

extern 「c」的作用不用多說了,但是需要說明的一點是:靜態載入方式下可以不需要這個,但是動態載入方式下是必需的。

即使兩種載入方式編譯時都順利通過,在執行時仍然可能出現找不到庫的情況,此時靜態方式會提示類似「./main: error while loading shared libraries: libdlltest.so: cannot open shared object file: no such file or directory」這樣的錯誤,動態方式會導致so_handle為空。此時可通過兩種方法解決這個問題:

2. 匯出類的動態庫

linux下動態庫中匯出模擬較麻煩,可參考下例進行。說明一下,這個例子參考了**略作了修改。

#ifndef base_class_h

#define base_class_h

class baseclass

virtual ~baseclass() {}

void set_member_var(int param)

virtual int get_member_var() const = 0;

};// the types of the class factories

typedef baseclass* create_t();

typedef void destroy_t(baseclass*);

#endif

#include "base.h"

class subclass : public baseclass

};// the class factories

extern "c" baseclass* create()

extern "c" void destroy(baseclass* p)

編譯生成動態庫:g++ -fpic -shared -o libsubclass.so subclass.cc

載入動態庫示例**:

#include using namespace std;

#include #include "base.h"

int main(int argc,char** argv)

create_t* create = (create_t*)dlsym(so_handle, "create"); // 載入函式

if (null == create)

destroy_t* destroy = (destroy_t*) dlsym(so_handle, "destroy");

if (null == destroy)

baseclass* pobj = create();

pobj->set_member_var(10);

cout << "pobj->get_member_var():" << pobj->get_member_var() << endl;

destroy(pobj);

dlclose(so_handle); // 關閉so控制代碼

}

編譯可執行程式:g++ -o main main.cc -ldl。很明顯,上述**採用了動態載入方式。其實匯出類的動態庫也可以採用靜態載入方式,示例**如下:

#ifndef base_class_h

#define base_class_h

class baseclass

virtual ~baseclass() {}

void set_member_var(int param)

virtual int get_member_var() const = 0;

};// the types of the class factories

typedef baseclass* create_t();

typedef void destroy_t(baseclass*);

#endif

#include "base.h"

class subclass : public baseclass ;

virtual ~subclass(){};

virtual int get_member_var() const;

};// the class factories

extern "c" baseclass* create()

extern "c" void destroy(baseclass* p)

#include "subclass.h"

int subclass::get_member_var() const

編譯生成動態庫:g++ -fpic -shared -o libsubclass.so subclass.cc

靜態載入示例**如下:

#include using namespace std;

#include #include "subclass.h"

int main(int argc,char** argv)

編譯可執行程式:g++ mainclass.cc -o mainclass -l./ -lsubclass

個人覺得靜態載入方式明顯的比動態載入方式麻煩,而且通用性不好,所以不建議使用。

上述**中需要注意乙個細節問題:如果subclass.h中不定義、只宣告subclass的析構函式,雖然生成動態庫時不會出錯,但是生成可執行檔案時,會報下列類似錯誤:

in function `subclass::subclass()':

mainclass.cc:(.text._zn8subclassc2ev[_zn8subclassc5ev]+0x1f): undefined reference to `vtable for subclass'

這個錯誤是乙個比較常見的錯誤,一般原因都是由於在繼承層次的類中,virtual函式沒有定義、只有宣告。比如上例中的base.h中,如果baseclass的析構函式如果缺失定義,也會出現類似錯誤。

Linux系統中靜態庫和動態庫的生成和使用

linuxeden超級qq群號 52348914 歡迎加入 一 靜態庫的建立和使用 1 生成靜態庫 庫名 libmylib.a ar rcs libmylib.a mylib.o 2 將靜態庫copy到 usr lib 或 lib 目錄下 cp libmylib.a usr lib 3 靜態庫的使用...

Linux系統中靜態庫和動態庫的生成和使用

一 靜態庫的建立和使用 1 生成靜態庫 庫名 libmylib.a ar rcs libmylib.a mylib.o 2 將靜態庫copy到 usr lib 或 lib 目錄下 cp libmylib.a usr lib 3 靜態庫的使用 比如測試檔案為test.c gcc 0 test test...

Linux下靜態庫和動態庫的生成

1.何為靜態庫 何為動態庫 windows下 dll 是動態庫 lib是靜態庫 linux下 so是動態庫 a是靜態庫 靜態庫 在生成可執行程式的時候,會把函式的具體執行方式封裝到程式中,程式體積比較大,只要能編譯成功,就可以在任意相同的平台上執行 動態庫 在生成可執行程式的時候,只會把函式的介面封...