從Linux and Windows中引入類
一般從Windows的動態(tài)庫引入類的方法比較簡單,只需要在DLL的類的申明出加入EXPORT就可以,但是這種方法只限于編譯的時候引入 DLL,就是通過Lib的方式引入DLL,但是很多情況下需要在程序的運行期來引入Dll,就像在程序運行的時候使用LoadLibrary獲得動態(tài)庫,然后通過GetProcAddr來取得函數在庫中的地址。怎樣能夠在運行的時候從動態(tài)庫中引入類的申明呢?
首先在Windows下看一看如何做:
我們知道,在DLL中的類實際上只是一個類型的申明,他并沒有實際的地址,所以希望通過地址來直接取出一個類的方法是無效的。雖然直接取不行,但是可以使用間接的方法,我們可以在DLL中創(chuàng)建一個全局函數或者靜態(tài)函數,用這個函數來創(chuàng)建一個類的對象,這樣我們就可以使用該類了。
看這一段申明DLL的代碼:
這個演示的類有兩個成員函數,一個是init()函數,用來初始化成員變量,另一個是print()函數,用來輸出成員變量。為了使這個類能夠被外部程序使用,我們?yōu)樗砑恿藘蓚成員函數,請見下面:
1.Create()函數,他用來創(chuàng)建一個MyClass的對象,并且返回一個指向該類的指針。
2.Destroy()函數,他用來銷毀前面創(chuàng)建的MyClass的對象指針并釋放資源。
通常一個類的所有成員函數都要在外部一一申明這樣才可以使用,這里我們使用了一個技巧,就是把所有的Public屬性的成員函數全部申明成virtual函數,利用虛函數自動與對象動態(tài)幫定的特性,這樣在使用時直接引用對象的成員方法就可以了。
#define EXPORT __declspec(dllexport)
class MyClass{
int x;
int y;
public:
//把Create和Destroy方法申明為靜態(tài)的和可供符號輸出的
EXPORT static MyClass * Create()
{
return new MyClass();
}
EXPORT static void Destroy(MyClass * mc)
{
delete mc;
}
virtual void init();
virtual void print();
};
在主程序使用動態(tài)庫中的類的方法:
首先定義函數指針類型
typedef MyClass* (*CreateMyClass)();
在主函數中:
//先LoadLibrary讀取DLL庫
HINSTANCE hInstance = LoadLibrary("MyDll.dll");
//用普通的GetProcAddress方法取得Create函數的地址;
CreateMyClass createMC =
(CreateMyClass)(GetProcAddress(hInstance,
MAKEINTRESOURCE(1)));
//然后用Create函數創(chuàng)建對象
MyClass *d = createMC();
//下面就可以使用該對象了。
d->init();
d->print();
下面介紹Linux下的動態(tài)庫中的類的輸出方法:
Linux的動態(tài)庫一般稱為共享庫(shared library),其特征是以“.so”為文件的擴展名。
同 WIindows一樣Linux下的動態(tài)庫的類的輸出也是要依靠動態(tài)庫中的一個全局函數或者靜態(tài)函數,與Windows中的輸出方法不一樣的地方是 Linux沒有__declspec(dllexport)關鍵字。但他必須把要輸出的函數申明為extern “C”類型的,這樣在GetProcAddr時候才能找到該地址
實例的Shared Library代碼如下:
#include
class MyClass{
int x;
int y;
public:
virtual void init();
virtual void print();
};
extern "C" {MyClass * Create()
{return new MyClass();
}
}
//1-2)linux shared library cpp file
#include "MyDll.h"
void MyClass::init()
{
x=3;
y=4;
}
void MyClass::print()
{
printf("%d%d\n",x,y);
}
主程序文件如下:
#define SHARED
#define SOFILE "./mydll.so"
#include
#include "dlfcn.h"
#include "Mytest.h"
using namespace std;
MyClass* (*CreateClass)();
int main()
{
void *dp;
char *error;
dp = dlopen(SOFILE,RTLD_LAZY);
if(dp == NULL)
{
cout<<"can't open file"<< p>
}
CreateClass =(MyClass*(*)())dlsym(dp,"Create");
error = dlerror();
新文章:
- CentOS7下圖形配置網絡的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統(tǒng)后丟失windows啟動項
- CentOS單網卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網打印機IP講解
- CentOS7使用hostapd實現無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網絡重啟出錯
- 解決Centos7雙系統(tǒng)后丟失windows啟動項
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統(tǒng)有什么不同呢
- Centos 6.6默認iptable規(guī)則詳解