歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 從Linux and Windows 的動態庫中引入類

從Linux and Windows 的動態庫中引入類

日期:2017/2/28 16:28:26   编辑:Linux教程

從Linux and Windows 的動態庫中引入類的方法

一般從Windows的動態庫引入類的方法比較簡單,只需要在DLL的類的申明出加入EXPORT就可以,但是這種方法只限於編譯的時候引入DLL,就是通過Lib的方式引入DLL,但是很多情況下需要在程序的運行期來引入Dll,就像在程序運行的時候使用LoadLibrary獲得動態庫,然後通過GetProcAddr來取得函數在庫中的地址。怎樣能夠在運行的時候從動態庫中引入類的申明呢?

首先在Windows下看一看如何做:

我們知道,在DLL中的類實際上只是一個類型的申明,他並沒有實際的地址,所以希望通過地址來直接取出一個類的方法是無效的。雖然直接取不行,但是可以使用間接的方法,我們可以在DLL中創建一個全局函數或者靜態函數,用這個函數來創建一個類的對象,這樣我們就可以使用該類了。

看這一段申明DLL的代碼:

這個演示的類有兩個成員函數,一個是init()函數,用來初始化成員變量,另一個是print()函數,用來輸出成員變量。為了使這個類能夠被外部程序使用,我們為她添加了兩個成員函數,請見下面:

1.Create()函數,他用來創建一個MyClass的對象,並且返回一個指向該類的指針。
2.Destroy()函數,他用來銷毀前面創建的MyClass的對象指針並釋放資源。

通常一個類的所有成員函數都要在外部一一申明這樣才可以使用,這裡我們使用了一個技巧,就是把所有的Public屬性的成員函數全部申明成virtual函數,利用虛函數自動與對象動態幫定的特性,這樣在使用時直接引用對象的成員方法就可以了。

#define EXPORT __declspec(dllexport)
class MyClass{
int x;
int y;
public:
//把Create和Destroy方法申明為靜態的和可供符號輸出的
EXPORT static MyClass * Create()
{
return new MyClass();
}
EXPORT static void Destroy(MyClass * mc)
{
delete mc;
}
virtual void init();
virtual void print();
};
在主程序使用動態庫中的類的方法:
首先定義函數指針類型
typedef MyClass* (*CreateMyClass)();
在主函數中:
//先LoadLibrary讀取DLL庫
HINSTANCE hInstance = LoadLibrary("MyDll.dll");

//用普通的GetProcAddress方法取得Create函數的地址;
CreateMyClass createMC =
(CreateMyClass)(GetProcAddress(hInstance,
MAKEINTRESOURCE(1)));
//然後用Create函數創建對象
MyClass *d = createMC();
//下面就可以使用該對象了。
d->init();
d->print();

下面介紹Linux下的動態庫中的類的輸出方法:
Linux的動態庫一般稱為共享庫(shared library),其特征是以“.so”為文件的擴展名。
同WIindows一樣Linux下的動態庫的類的輸出也是要依靠動態庫中的一個全局函數或者靜態函數,與Windows中的輸出方法不一樣的地方是Linux沒有__declspec(dllexport)關鍵字。但他必須把要輸出的函數申明為extern “C”類型的,這樣在GetProcAddr時候才能找到該地址

實例的Shared Library代碼如下:
#include <stdio.h>
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 <iostream>
#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"<<endl;
}
CreateClass =(MyClass*(*)())dlsym(dp,"Create");
error = dlerror();
if(error)
{
cout<<"can't get symbol"<<endl;
}
MyClass *d = CreateClass();
d->init();
d->print();
linux makefile文件內容如下:
all:
gcc -c mydll.cpp
gcc -shared -o mydll.so mydll.o
g++ -c mytest.cpp
g++ -rdynamic -s -o mytest mytest.cpp -ldl

Copyright © Linux教程網 All Rights Reserved