我需要檢查動態庫是否存在,以便稍後可以安全地調用使用此庫的函數。確定動態庫是否存在的多平臺方法
有沒有多平臺的方法來檢查這個?我的目標是MS Windows 7(VC++ 11)和Linux(g ++)。
我需要檢查動態庫是否存在,以便稍後可以安全地調用使用此庫的函數。確定動態庫是否存在的多平臺方法
有沒有多平臺的方法來檢查這個?我的目標是MS Windows 7(VC++ 11)和Linux(g ++)。
要動態「使用」共享庫中的函數,需要該庫不是可執行文件的一部分,因此您需要編寫代碼來加載庫,然後使用該函數。可能有辦法以便攜的方式來做到這一點,但我不知道有任何代碼可以做到這一點。
這不是很難寫的代碼。爲「步驟」,它涉及到以下內容:
如果第1步失敗,那麼你的庫不存在(或以其他方式「行不通」),所以你不能調用函數在它...
顯然,有很多設計接口來提供這種類型的功能的方法,以及你如何去做,取決於你的實際問題設置。
編輯:
爲了澄清直接使用DLL,並使用一個使用從所述碼動態加載之間的差值:
想象這是我們的「shared.h」,它定義爲功能共享庫 (可能有一些declspec(...)
或exportsymbol
或其他類似的東西在一個真正的頭,但我現在完全忽略)。
int func1();
char *func2(int x);
在一段代碼,直接使用DLL,你只是做:
#include <shared.h>
int main()
{
int x = func1();
char *str = func2(42);
cout << "x=" << x << " str=" << str << endl;
return 0;
}
相當直接的,對不對?
當我們使用動態的代碼加載的共享庫,它得到一個公平的有點複雜:
#include <shared.h>
typedef int (*ptrfunc1)();
typedef char * (*ptrfunc2)(int x);
int main()
{
SOMETYPE handle = loadlibrary("shared");
if (handle == ERROR_INDICATOR)
{
cerr << "Error: Couldn't load shared library 'shared'";
return 1;
}
ptrfunc1 pf1 = reinterpret_cast<ptrfunc1>(findfunc("func1"));
ptrfunc2 pf2 = reinterpret_cast<ptrfunc2>(findfunc("func2"));
int x = pf1();
char *str = pf2(42);
cout << "x=" << x << " str=" << str << endl;
return 0;
}
正如你看到的,代碼一下子得到了很多更加「混亂」。不要緊,你必須跳過尋找QObject
的構造函數,或者更糟糕的是,從QObject
繼承。換句話說,如果你在你的代碼中使用Qt,你可能會直接鏈接到「qt.lib」,如果你的應用程序沒有安裝Qt環境,你的應用程序將會崩潰。
請注意:我使用eg。 qt.lib中的Qt函數(假設存在這樣的lib),並且這些函數本身加載一個DLL。如果它們失敗,我的整個應用程序將失敗所以我想通過在試圖加載之前手動檢查DLL是否存在來防止這種情況。你明白嗎? – Parobay
是的,實現這一目標的唯一方法是不首先將'qt.lib'鏈接到您的應用程序中,然後使用您編寫的代碼來檢查您是否可以加載'qt.dll',並且然後使用它。但是對於qt來說這將是一個非常糟糕的任務,因爲它沒有一個簡單的界面。這是一大堆功能。而qt的全部重點是使代碼可移植並在多個平臺上編譯相同。這將是一個更好的選擇,建立一個安裝程序,檢查是否和/或確保安裝qt'會導致應用程序的安裝。 –
我要說的是,如果你使用'qt.lib'鏈接,系統加載器將在應用程序啓動時自動加載'qt.dll'或'qt.so' - 如果共享庫不是在那裏,它會使可執行文件的負載失效。這是可執行程序及其組成共享庫如何在正常系統中加載的一部分。你不能改變它,除非你停止使用'qt.lib',這又意味着你不能只在代碼中使用Qt函數。您必須通過一個接口來調用它們,以檢查它們是否可用,如果不可用,則執行其他操作。 –
LoadLibrary調用應該失敗,那麼你可以知道動態庫是否存在。還有動態加載,你會從動態庫中獲得函數指針,如果指針爲空,那麼平臺不支持該平臺上的那個函數。
在windows上您有LoadLibrary
API來加載動態庫。和GetProcAddress
API在該lib中查找所需的函數。如果GetProcAddress
針對您正在查找的特定功能返回NULL,則該平臺不存在該功能。您可以記錄然後決定回退。
LoadLibrary調用應該失敗,那麼你可以知道。另外動態加載你從dll得到函數指針,如果指針爲空,那麼平臺不支持那個平臺上的那個函數。問題是什麼? –
如果庫無法加載,那麼我的應用程序崩潰 - 我想避免這種情況。這種情況是我使用了一些庫(靜態鏈接),期望它們的運行時助手動態庫。 – Parobay
對於POSIX變體(如Linux和Mac OSX),請查找['dlopen'](http://pubs.opengroup.org/onlinepubs/009695399/functions/dlopen.html)和['dlsym'](http:// pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html)。沒有我知道的跨平臺庫,但它很簡單,您可以使用非常類似的代碼來檢查Windows和Linux(相同的佈局,只是不同的功能)。 –