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是靜態庫 靜態庫 在生成可執行程式的時候,會把函式的具體執行方式封裝到程式中,程式體積比較大,只要能編譯成功,就可以在任意相同的平台上執行 動態庫 在生成可執行程式的時候,只會把函式的介面封...