8

I have a program do so some graphics. When I run it interactively, I want it to use OpenGL from the system to provide hardware accelerated graphics. When I run it in batch, I want to be able to redirect it to use the Mesa GL library so that I can use OSMesa functionality to render to an offscreen buffer. The OSMesa functionality is enabled by doing a LoadLibrary/GetProcAddress if the batch start up option is selected.

On Linux, its fairly easy to make this work. By using a wrapper script to invoke the program, I can do something like this:

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

It is possible to do something this in Windows?

When I try adding a directory to the PATH variable, the program continues to go to the system opengl32.dll. The only way I can get the program to use the Mesa GL/OSMesa shared libraries is to have them reside in the same directory as my program. However, when I do that, the program will never use the system opengl32.dll.

4

4 に答える 4

8

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

opengl32.dll への呼び出しが Qt ライブラリから来ているため、opengl32.dll に対して実行時の動的リンク(LoadLibrary/GetProcAddress) を便利に使用できないと言っています。ただし、Qt ライブラリ自体は動的にリンクされていると思われるため、実行時リンクを使用して問題を解決できるはずです。このシナリオでは、Qt ライブラリをロードする前に opengl32.dll をロードすると、ロードする opengl32.dll のバージョンを明示的に選択できるはずです。

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

于 2012-02-01T04:04:08.843 に答える
1

ライブラリとその名前/場所に応じて、これを処理する方法がいくつかあります。

両方が同じ名前 (opengl32.dll) の場合、システム ディレクトリのに検索されるように、検索パスに Mesa DLL の場所を追加する必要があります。ディレクトリがチェックインされる順序については、こちらで詳しく説明しています。ご覧のとおり$PATH、システムの後に が最後に来るので、そこにディレクトリを追加することはできません。ただし、作業ディレクトリを mesa ファイルを含むパスに設定することにより、2 番目のステップ (「現在のディレクトリ」) を利用できます。通常、これは、ファイルを含むディレクトリ内で絶対パスを使用してアプリケーションを開始することを意味します。

しかし、それはまだ特に楽しいことではありません。可能であれば、アプリの起動時にLoadLibrary環境変数 ( ) を使用して確認する必要があります。OPENGL_LIBRARY_PATHからのエクスポートopengl32.dllと Mesa の DLL が同じであると仮定すると、次のようなことができます。

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

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

これは完全にうまく機能し、ほぼ正確にあなたが望むことをします。

ただし、それを行いたい場合は、インポートすることはできませんopengl32.dll。これはおそらく行っているため、動的にリンクする必要があります。リンクしないように注意してくださいopengl32.lib。問題ありません。使用する関数の数によっては、セットアップが面倒になる場合がありますが、コードは簡単にスクリプト化でき、一度実行するだけで済みます。また、static変数を使用して、プログラムの存続期間中の結果をキャッシュすることもできます。ライブラリごとに異なる関数名を使用することもできますが、これにはもう少しロジックが必要なので、詳細はお任せします。

于 2012-01-30T13:58:39.153 に答える
0

Windowsは、ダイナミックライブラリのさまざまなパスを検索するために使用されていましたが、セキュリティ上の理由から、システムパスが最初に検索されます。

ただし、DelayLoadImportsを使用して回避策を取得することはできます。

/DELAYIMPORTMSVCを使用している場合は、リンカへのフラグを使用して、ロードする必要のあるDLLを自分で選択することができます。

次に、遅延ロードヘルパー関数をオーバーライドし、を使用LoadLibraryして適切なDLLを見つけます(システムに信頼しないでください)。

正しいDLLをロードした後、ヘルパー関数に、すべてのGetProcAddressビジネスを単独で実行する元のDLLを呼び出すようにします。

于 2012-02-01T12:59:43.770 に答える
0

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

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

于 2012-01-25T19:08:47.423 に答える