多平臺加載動態鏈接庫總結

多平臺加載動態鏈接庫總結


1、Linux, SunOS, Solaris, IRIX, FreeBSD,NetBSD, AIX 4.2, HPUX 11,和其它類Unix系統
頭文件:#include <dlfcn.h>


加載:void *dlopen(const char *filename, int flag); 
      示例:void* hnd = dlopen(path,RTLD_NOW) path是動態庫路徑,void*是加載後的句柄
      flag的類別:
          RTLD_LAZY:在dlopen返回前,對於動態庫中存在的未定義的變量(如外部變量extern,也可以是函數)不執行解析,就是不解析這個變量的地址。
          RTLD_NOW:與上面不同,他需要在dlopen返回前,解析出每個未定義變量的地址,如果解析不出來,在dlopen會返回NULL
          RTLD_GLOBAL:它的含義是使得庫中的解析的定義變量在隨後的其它的鏈接庫中變得可以使用。
          RTLD_LOCAL


調用:void* dlsym(void* handle,const char* symbol)
      示例:void* func = dlsym(hnd,"func")執行後,func裏存的就是動態庫里名字爲func的函數或全局變量的地址


卸載:int dlclose (void *handle);
只有當此動態鏈接庫的使用計數爲0時,纔會真正被系統卸載。


2、windows
頭文件:#include <windows.h>


加載:HINSTANCE lib = LoadLibraryA(path);


調用:GetProcAddress((HINSTANCE)lib, sym);


卸載:FreeLibrary((HINSTANCE)lib);


3、mac os
頭文件:#include <mach-o/dyld.h>


加載: void* hnd = NULL;
NSObjectFileImage img;
       NSObjectFileImageReturnCode ret;
       if(!_dyld_present()) 
{
return;
}
if(NSObjectFileImageSuccess == NSCreateObjectFileImageFromFile(path, &img))
{
NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
                NSDestroyObjectFileImage(img);
hnd = mod;
}
調用:NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
      void* func = NSAddressOfSymbol(nss);
      


卸載:NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);


///////////////////////////////////////////////////////////////////////////////////
動態鏈接庫構造和析構功能函數實現
windows裏的話會自動調用下面的函數
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
但linux類系統裏不會這麼調用,而是會調_init和_finit,
但這兩個函數都是gcc佔用的,它們會做初始化全局變量等操作,我們
不能直接改寫,只能通過下面的方式來實現需求。
1、利用c++類的構造和析構函數實現
class module
{
module()
{
//do init here
}
~module()
{
//do finit here
}
};


static module g_module;


2、利用gcc擴展實現
__attribute((constructor)) void module_init()
{
//do init here
}
__attribute((destructor)) void module_finit()
{
//do finit here
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章