いくつかの制限により、実行時にCで記述されたライブラリをロードする必要があります。サードパーティは、共有オブジェクトに変換する静的アーカイブとして2つのライブラリを提供してくれます。私が使用しているアプリケーションは、いくつかのハードウェアパラメータに基づいて、実行時にライブラリの1つをロードします。残念ながら、ライブラリの1つは主にグローバル変数で構成されています。
すでに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 で void* を使用するシステムでは、ポインターを変換できる必要があることは明らかです。(Microsoft の GetProcAddress は独自のポインター型を返します。この場合、必要に応じて後で実際の意味を変更できるため、より良い選択だと思います)。
私は C++ でそれを行っているので、そのようなエクスポートされたオブジェクトが共通の基本クラスから派生することを強制できます。次に、そのクラスから実際のクラスへの dynamic_cast を使用できます。これは、エラーが後のクラスから派生していない場合にエラーをキャッチできることを意味し、実行時エラーを後で保存します。