6

後でこのライブラリを使用する関数を安全に呼び出せるように、動的ライブラリが存在するかどうかを確認する必要があります。

これを確認するマルチプラットフォームの方法はありますか? MS Windows 7 (VC++11) と Linux (g++) をターゲットにしています。

4

2 に答える 2

4

共有ライブラリの関数を動的に「使用」するには、ライブラリが実行可能ファイルの一部ではない必要があるため、ライブラリをロードして関数を使用するコードを記述する必要があります。移植可能な方法でそれを行う方法があるかもしれませんが、それを行うために利用できるコードは知りません。

書くのはそれほど難しいコードではありません。「ステップ」として、次のことが含まれます。

  1. ファイル名を指定してライブラリをロードします (たとえば、"xx" は、アーキテクチャ固有のコードで "xx.so" または "xx.dll" に変換されます)。
  2. インデックス (「関数番号 1」) または名前 (「関数 blah」) のいずれかに基づいて関数を検索し、アドレスを返します。
  3. 関連するすべての関数について、手順 2 を繰り返します。
  4. ライブラリが不要になったら、提供されたハンドルで閉じます。

ステップ1が失敗した場合、ライブラリが存在しない(または「機能しない」)ため、そのライブラリで関数を呼び出すことはできません...

明らかに、この種の機能を提供するインターフェイスを設計する方法は数多くあります。実際にどのように設計するかは、実際の問題設定によって異なります。

編集:

DLL を直接使用する場合と、コードからの動的読み込みを使用して 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 環境がマシンにインストールされていないとアプリケーションがクラッシュする可能性があります。

于 2013-04-10T12:17:22.003 に答える