10

私の基本的な問題はこれです:私のプログラム(MyProgram.exe)は別のプログラム(OtherProgram)からのDLLに依存しており、OtherProgramが更新されるたびに新しいDLLを再パッケージ化しないようにしています。起動時にOtherProgramのDLLにMyProgram.exeリンクを設定したいのですが、Windowsでこれが可能かどうかは完全にはわかりません。したがって、何らかの回避策がある場合は、それも許容されます。

また、背景として、プラットフォームはWindows 7 x64であり、MyProgram.exeプロジェクトディレクトリにOtherProgramのインストールディレクトリのDLLへのシンボリックリンクを作成すると、MyProgram.exeは正常に実行されます。シンボリックリンクなしで実行しようとすると、「OtherProgramDLL.dllがコンピュータにないため、プログラムを開始できません」というエラーが表示されます。

アドバイスや関連情報へのリンクは大歓迎です!

編集:明確化:DLLはコンパイル時にリンクされません、この問題は実行時に発生します

4

6 に答える 6

12

Windowsの世界には2種類のダイナミックリンクがあります。

  1. ロード時のリンクは、プログラムの起動時にDLLが自動的にロードされる場合です。Windowsは、以下で説明する特定のアルゴリズムを使用してこのDLLを検出します。
  2. ランタイムリンクは、コードを呼び出してDLLLoadLibrary具体的にロードする場合です。ライブラリの検索方法についても同様のルールが適用されますが、検索を制御するために完全修飾パスまたは比較的修飾パスを指定できます。

Load-Timeリンクの場合、MSは、プログラムのDLLを、アプリケーションのロード元と同じディレクトリに格納してロードすることをお勧めします。これがまったく実行可能である場合、これはおそらく最良のオプションです。

それがうまくいかない場合は、ここで概説する他のいくつかのオプションがあります。1つは、DLLを作業ディレクトリまたはアプリケーションのロード元のディレクトリに配置することにより、検索順序を活用することです。

アプリケーションの作業ディレクトリは、次の方法で変更できます。

  1. アプリケーションへのショートカットを作成します。
  2. ショートカットのプロパティを表示します
  3. DLLが配置されているディレクトリで「Startin」プロパティを編集します。

ショートカットを使用してアプリケーションを起動すると、適切なDLLがロードされます。

ロード時リンクのその他のオプションは次のとおりです。

  • 依存アセンブリがどこにあるかを指定するマニフェストをアプリケーションに追加する、または、
  • の設定PATH
于 2012-05-15T19:16:36.480 に答える
3

LoadLibraryを使用することもできますが、DLLの場所を保証する方法が必要になります。このウィキペディアの記事は、ロード後にDLLを使用する方法の良い例を提供します。

于 2012-05-15T18:10:40.227 に答える
1

dllが配置されているディレクトリをPATH環境変数に追加できます。

于 2012-05-15T18:03:21.440 に答える
1

私は同じ問題に苦しんでおり、、、、QtなどLoadLibraryの提案された方法で行き止まりを見つけました。私が何を試したかに関係なく、アプリケーションが実際にコードを実行する前にライブラリをチェックした(そしてライブラリを見つけられなかった)という問題が残っていたため、コードソリューションは必ず失敗しました。SetDllDirectoryaddLibraryPath

私はほとんど必死になりましたが、それからあなたのような場合にも役立つかもしれない非常に簡単なアプローチを発見しました:バッチファイルを使用してください!(または実際のアプリケーションの前の同様のローダー)

このような目的のWindowsバッチファイルは次のようになります。

@echo off
PATH=%PATH%;<PATH_TO_YOUR_LIB>
<PATH_TO_YOUR_APP_EXE>

/ edit:そのように説明しているLuchianの回答で@SirDariusのコメントを見たので、私のバッチコードビットを参照してください。すべてのクレジットが彼に送られます。

于 2015-06-15T15:10:00.067 に答える
1

作業中の1つのアプリケーションで同じ問題が発生します。

関数ポインタを手動で作成する必要がある関数が数十あるため、ランタイムロードを使用したくありません。

マニフェストファイルについてのDibling氏の言及は、私にとって新しい扉を開きましたが、残念ながら、この機能をサポートする最も古いバージョンのWindowsがWindows7であることがわかりました。Vistaでも動作しません。

簡単に言うと、Windowsアプリケーション開発に精通している友人から、遅延ロードDLLを検索するように言われました。これにより、最小限の労力で問題を完全に解決できることがわかりました。DLLライブラリのロードを、手動で行うか、その関数が最初に呼び出された時点まで遅らせます。したがって、それが発生する前に、DLLパスを検索パスに追加する必要があります。SetDllDirectoryが役立ちます。

これを機能させるための手順は次のとおりです。

1)makefile、cmake、またはVSプロパティページ([リンカー]-> [VS2015の入力])のいずれかを使用して、リンカーに遅延ロードするDLLを指定します。

2)DLLを呼び出す前に、プログラムの先頭でSetDllDirectoryを呼び出します。

遅延ロードされたDLLは、VC6までずっとサポートされています。SetDllDirectoryは、XPSP1以降でサポートされています。

于 2017-10-01T01:38:41.287 に答える
0

サードパーティの実行可能ファイルへのシンボリックリンクを使用する

AaronMargosisが提唱するアプローチは役に立ちました。見る:

NTFSジャンクションを使用して64ビット版のWindowsでアプリケーションの互換性の問題を修正する

基本的に、依存するサードパーティの実行可能ファイルのそれぞれへのシンボリックリンクを作成します。これらのシンボリックリンクファイルを、依存する実行可能ファイル内およびファイル間に配置します。ターゲットへのファイル名の変更を除いて、「ソフト」シンボリックリンクは、リンクのターゲットが将来の更新によって変更された場合でも、ロード時の依存関係を解決します。

于 2017-04-06T21:17:25.373 に答える