由於一些限制,我在運行時被迫加載用C編寫的庫。第三方爲我提供了兩個庫作爲靜態檔案,我們將它們變成共享對象。我正在使用的應用程序根據一些硬件參數在運行時加載其中一個庫。不幸的是其中一個庫大部分都配置了全局變量。dlopen和C/C++中的全局變量
我已經使用dlsym來加載函數引用,但是我可以使用dlsym來加載對這些全局變量的引用嗎?
由於一些限制,我在運行時被迫加載用C編寫的庫。第三方爲我提供了兩個庫作爲靜態檔案,我們將它們變成共享對象。我正在使用的應用程序根據一些硬件參數在運行時加載其中一個庫。不幸的是其中一個庫大部分都配置了全局變量。dlopen和C/C++中的全局變量
我已經使用dlsym來加載函數引用,但是我可以使用dlsym來加載對這些全局變量的引用嗎?
是的,你可以使用dlsym來訪問全局變量(只要它們是導出的,而不是靜態的)。下面的例子是在C++和Mac中,但顯然C將工作正常。
lib.cpp:
extern "C" {
int barleyCorn = 12;
}
uselib.cpp
#include <dlfcn.h>
#include <iostream>
using namespace std;
main()
{
void * f = dlopen ("lib.dylib", RTLD_NOW);
void * obj = dlsym (f, "barleyCorn");
int * ptr = (int *) obj;
cout << *ptr << endl;
}
輸出:
% ./a.out
12
是的,您可以使用dlsym()
在動態庫中找到任何導出的符號。
是的,你可以和我實際寧願做這個而不是加載函數。我的標準IOC模型就是這樣做的。
我喜歡它,因爲:
從一個void *的轉換爲指針,以一個對象在技術上比函數指針更安全,雖然很明顯,使用無效的系統*使用dlsym必須允許你要轉換指針。 (微軟的GetProcAddress返回他們自己的指針類型,在這種情況下,我認爲這是一個更好的選擇,因爲如果他們需要,他們可以在以後改變它的實際含義)。
因爲我在C++中執行它,所以我可以強制執行任何這樣的導出對象派生自一個公共基類,然後我可以從該類中使用dynamic_cast到我期望的實際類。這意味着如果它不是從後面的類派生出來的,那麼可以捕獲一個錯誤,以後再保存運行時錯誤。
即使您從C運行時加載C++庫,您的全局對象也將被構造!當你卸載它時會被破壞 – yanpas 2017-09-05 17:04:54