2011-10-02 8 views
15

C++で書かれた、異なるオペレーティングシステム用にコンパイルされた共有ライブラリを使用するJavaアプリケーションをビルドします。問題は、この共有ライブラリ自体が、適切な環境変数(PATH、LIBRARY_PATHまたはLD_LIBRARY_PATH)で通常見つかる追加のライブラリに依存することです。実行時に共有ライブラリをパスでロードする

これらの環境変数は設定できますが、設定したくない場合もあります。私は、プラグインのように、ランタイムに必要な共有ライブラリを指定されたパスからロードします。そして、いいえ、新しい環境で新しいプロセスを開始する起動アプリケーションは必要ありません。誰もこれを達成する方法を知っていますか?

私が使用するライブラリの1つは、指定されたパスからプラグインを読み込むことができるので、これが可能でなければならないことは知っています。もちろん、私はプラットフォームに依存しないコードを好んでいますが、これが不可能な場合は、Windows、Linux、MacOS用の別々のソリューションでも可能です。

EDIT 私が使用したいと思い、共有ライブラリは、単一機能の結合は、それをしないことを意味し、オブジェクト指向であることを言及している必要があります。

+0

Javaからライブラリをロードするにはどうすればよいですか? –

+0

Javaネイティブアクセス(JNA) – aRestless

答えて

8

Windowsでは、LoadLibrary、Linuxではdlopenを使用できます。 APIは非常に似ており、完全なパスを提供することによってso/dllを直接ロードすることができます。これは、実行時依存関係の場合(読み込み後、GetProcAddress/dlsymを呼び出してリンクします)

15

Un UNIX/Linuxシステムの場合は、dlopenを使用できます。そこにあるから()

typedef int (*some_func)(char *param); 

void *myso = dlopen("/path/to/my.so", RTLD_NOW); 
some_func *func = dlsym(myso, "function_name_to_fetch"); 
func("foo"); 
dlclose(myso); 

の.soをロードするとfunction_name_to_fetchを実行します。問題は、あなたがdlsym

簡単な例を経由して、あなたが必要とするすべてのシンボルを取得する必要があります。詳細については、dlopen(1)のマニュアルページを参照してください。

+0

私は共有ライブラリ自体がオブジェクト指向であると付け加えておくべきだと思います。関数だけが "リンク"することができれば、これはうまくいかないでしょうか? – aRestless

+0

リンカが生成する名前が分かっていれば、任意のシンボルにアクセスできます。オブジェクトや何かを含む構造体へのポインタを返すCの呼び出し規約を使用する関数を用意するのがよい方法です。 – johannes

+0

さて、私は既にそれを行います - Javaを介してライブラリにアクセスする。私が書いているC++ライブラリは、サードパーティのライブラリ(私は変更できません)を使ったスタブです。 – aRestless

1

私はあなたがそれを行うことはできないと思います。

ほとんどのDLLは、ロードされた後に呼び出されなければならない何らかの種類のinit()関数を持っていて、何らかのパラメータを必要とし、DLLの関数を呼び出すために使用するハンドルを返します。あなたは追加のライブラリの定義を知っていますか?

その後、最初のライブラリはDLL Xがその名前を使ってのみRAMにあるかどうかを単純に見ることはできません。必要なものは、別のディレクトリや別のビルド/バージョンに置くことができます。完全なパスがすでにロードされているものと同じであれば、OSはライブラリを認識し、2回目のロードではなく共有します。

他のライブラリは、PATHに依存しないように書かれたもので、自分のプラグインであるため、別のパスからプラグインを読み込むことができます。

Dllをロードする前に、プロセスの環境変数をコードから更新しようとしましたか?それはスタータープロセスに依存しません。

3

他のポスターとdlopenとLoadLibraryの使用について同意します。 libltdlは、これらの機能にプラットフォームに依存しないインタフェースを提供します。

関連する問題