2012-01-25 5 views
4

私はプログラムをいくつかのグラフィックスを持っている。インタラクティブに実行すると、システムからOpenGLを使用して、ハードウェアアクセラレーションされたグラフィックスを提供したいと考えています。私はそれを一括して実行するときに、Mesa GLライブラリを使用するようにリダイレクトして、OSMesa機能を使ってオフスクリーンバッファにレンダリングできるようにしたいと考えています。 OSMesa機能は、バッチ起動オプションが選択されている場合にLoadLibrary/GetProcAddressを実行すると有効になります。WindowsでLD_LIBRARY_PATHをシミュレートする方法はありますか?

Linuxでは、この作業をかなり簡単に行うことができます。 Windowsで何かこれを行うことが可能である

if [ "$OPTION" = "batch" ]; then 
    export LD_LIBRARY_PATH=$PATHTO/mesalibs:$LD_LIBRARY_PATH 
fi 

:プログラムを起動するために、ラッパースクリプトを使用して、私はこのような何かを行うことができますか?

PATH変数にディレクトリを追加しようとすると、プログラムは引き続きopengl32.dllシステムに移動します。私がMesa GL/OSMesa共有ライブラリを使用するためのプログラムを入手できる唯一の方法は、プログラムと同じディレクトリにそれらを置くことです。しかし、私がそうすると、プログラムはopengl32.dllシステムを使用しません。

答えて

4

あなたが正しく言っていることを理解していれば、プロセスが起動したときに間違ったバージョンのopengl32.dllがロードされています。つまり、load-time dynamic linkingです。おそらく、これを変えずに問題を解決する良い方法はありません。

opengl32.dllの呼び出しがQtライブラリからのものであるため、run-time dynamic linking(LoadLibrary/GetProcAddress)を便利に使用することはできません。私は、Qtライブラリ自体が動的にリンクされていると仮定しているため、ランタイムリンクを使用して問題を解決できるはずです。このシナリオでは、Qtライブラリをロードする前にopengl32.dllをロードすると、ロードするopengl32.dllのバージョンを明示的に選択できるはずです。

ロード時から実行時リンクへの移行プロセスを簡略化するために、delayed loadingの使用を検討することをお勧めします。このシナリオでは、Qtライブラリへの最初の呼び出しにより、Qtライブラリが自動的にロードされ、まずopengl32.dllを明示的にロードする必要があります。

+0

遅延ロードが鍵です。また、opengl32.dllとglu32.dllの両方が遅延ロードに設定されている必要があります。私はプログラムをバッチモードで起動した場合、ロードOpenGL32.dllとglu32.dllを遅延させて、これらの2つのDLLでLoadLibraryを呼び出すためのコードを入力するように実行ファイルを設定しました。このコードはQtライブラリへの最初の呼び出しの前に挿入されました。 – likso

0

これはcmdウィンドウでは可能ですが、運がないようです。

試してみてください:あなたのスクリプト(RUNNING_IN_SCRIPT = Y)で変数を設定してから、その実行可能ファイルとLoadLibraryを絶対パスから解析してください。終了時に必ず変数をクリアしてください。

+0

おそらく私は不明瞭でした - 私はosmesa32.dllのLoadLibraryのみを行います。 opengl32.dllは暗黙的にリンクされています。私は、システムopengl32.dllをMesa opengl32.dllに置き換える方法を見つけようとしています。 Linuxでは、LD_LIBRARY_PATHを使用してこれを行うことができますが、Windowsでは固執していると思いますが、そうではないと思っています。 – likso

+0

もちろん、変数が 'Y'に設定されているときにLoadLibraryを呼び出すだけで、そうでない場合はそのコードをスキップします。これは素晴らしい解決策ではないことに注意してくださいが、それは動作します – KevinDTimm

+0

これは私が理解していない部分です。私のスクリプトは変数を設定してからバッチモードでプログラムを起動します。私のプログラムが起動し、自動的にopengl32.dllシステムがロードされます。私のプログラムがバッチモードで起動されたかどうかを調べる部分に到達するまでに、opengl32.dllシステムは既にロードされています。 LoadLibrary( "H:\\ PATH \\ TO \\ mesa \\ opengl32.dll")を実行しようとすると、すでにロードされているopengl32.dllシステムをどのように置き換えることができますか? – likso

0

あなたがこれを扱うことができるいくつかの方法がライブラリとそれらの名前/場所に応じて、あります

両方が同じ名前(OPENGL32.DLL)を持っている場合は、あなたがメサDLLの場所を追加する必要がありますの前に、システムディレクトリののような検索パス。ディレクトリがチェックインされている注文ディレクトリの詳細はhereです。ご覧のとおり、$PATHがシステムの後に来るので、ディレクトリを追加するだけでは問題ありません。ただし、作業ディレクトリをメサファイルを含むパスに設定することで、2番目のステップ(「現在のディレクトリ」)を利用することができます。一般に、これは、ファイルを含むディレクトリ内に絶対パスを使用してアプリケーションを開始することを意味します。

これはまだ特に気分が良いことではありません。可能であれば、LoadLibraryを使用し、アプリ起動時に環境変数(OPENGL_LIBRARY_PATH)を確認する必要があります。ほぼ正確に何をしたいやって、完全に正常に動作します

void LoadExports() 
{ 
    char location[MAX_PATH]; 
    getenv("OPENGL_LIBRARY_PATH", location); 
    HMODULE oglLib = LoadLibrary(location); 

    function1 = GetProcAddress(oglLib, "glVertex2f"); 
    ... 
} 

この:opengl32.dllとメサのDLLからの輸出が同じことをしていると仮定すると、あなたのような何かを行うことができます。

しかし、もしそうしたいのであれば、実際にはopengl32.dllをインポートすることはできません。あなたは動的にリンクする必要があります。 opengl32.libとリンクしていないことを確認してください。使用する関数の数に応じて、設定するのが苦しいかもしれませんが、コードを簡単にスクリプト化して一度だけ実行するだけで済みます。また、static変数を使用してプログラムの有効期間中の結果をキャッシュすることもできます。また、ライブラリごとに異なる関数名を使用することもできますが、それにはもう少し論理が必要なので、詳細を残しておきます。

+0

はい、どちらも同じ名前のopengl32.dllを持っています。私はすでに "現在のディレクトリ"を使用しようとしました - それは動作しません。現在のディレクトリは、検索ディレクトリのシステムディレクトリの後ろにあります。 GetProcAddressを行うようにコードを修正することも考えましたが、すべてのOpenGL呼び出しがQtライブラリから来ているので、これは望ましくありません。現時点では、同じ実行可能ファイルを別々のディレクトリに置くという愚かな手法に頼っています.Mesaライブラリを持つディレクトリの1つが実行可能ファイルに存在し、dll検索順序に基づいてロードされます。 – likso

+0

あなたのライブラリがQtの前にロードされることが分かっているなら(またはスタブを作ることができる)ことが分かっているなら、そこから目的のライブラリの 'LoadLibrary'を呼び出してロードされたモジュールこの名前はQtライブラリがロードされるときに存在します。リンカーは 'opengl32.dll'をチェックし、すでにロードされている場合は* that *を使用します。それ以外の場合は、ロード・オーダーを処理し、依存関係/プロセス・トレース・ツールでどのパスを検索しているかをチェックする必要があります。 – ssube

+0

あなたはこの「トリック」についてもっと詳しく知っていますか?私は単純なテストプログラム(KevinDTimmによって既に提案されているように)でこのようなことをやろうとしました。ここでは、Mesaのopengl32.dllとosmesa32.dllでLoadLibraryを行い、OSMesaCreateContext、OSMesaMakeCurrent、glGetIntegervを呼び出しました。私が特にMesaライブラリを同じディレクトリに置かない限り、テストプログラムは常にopengl32.dllシステムを取得します。 – likso

0

動的ライブラリのさまざまなパスを検索するために使用されるWindowsが、セキュリティの考慮事項のために、システムパスが最初に検索されます。

あなたが、しかし、回避策を得るために遅延ロードインポートを使用することができ

あなたはMSVCを使用している場合、あなたは可能性があり、単一のアウトあなたがリンカに/DELAYIMPORTフラグを使用して独自にロードすることに興味のDLL 。

次に、delay load helper functionを無効にし、LoadLibraryを使用して、適切なDLLを見つけます(システムに信頼されません)。

正しいDLLを読み込んだ後で、ヘルパー機能は、GetProcAddressのすべてのビジネスを単独で行うオリジナルのものを呼び出すようにしてください。

関連する問題