2009-11-17 2 views
6

私はいくつかの.oファイルで構成自分のDLLをコンパイルしています。 .oのいずれかのファイルは、Windows 7のみでサポートされていSHLoadLibraryFromItemを呼び出す機能があります。関数が呼び出されることはありませんDLLを使用するアプリケーションは、Windows 7上で実行されていない限り(はい、私は確信しています。)DLLを別のWindowsバージョンで使用するにはどうすればよいですか?

をただし、Windows(たとえば、XP)の古いバージョンのアプリケーションを実行する際に、起動時にアプリケーション全体がクラッシュし、「指定されたプロシージャを見つけることができませんでした」というエラーが表示されます。手順指定しないエラーが見つかりませんでしたが、私はSHLoadLibraryFromItemへの呼び出しをコメントアウトした場合、その後、すべてが正常に動作します。

質問:

  1. はなぜWindowsはそれがXP上で呼び出されていないにもかかわらず、SHLoadLibraryFromItemを見つけるためにしようとしていますか?
  2. Windowsを使用する方法はありますかではなく、となります。つまり、Windows 7を実行しているとき、つまり何らかのレイジーバインディングしか見つからない場合はSHLoadLibraryFromItemとなりますか?
  3. ない場合は、この問題に対処する最善の方法は何ですか?

唯一の方法は、どちらか私は考えることができるよう、これを回避しているのです。

  1. 使用LoadLibrarySHLoadLibraryFromItemがであることをWindowsのDLLをロードし、ポインタ対に手動でアドレスを取得するためにGetProcAddressを使用します代わりにSHLoadLibraryFromItemを呼び出すためにポインタを使用しますか?
  2. は、2つのDLLを持っている:

他のアイデアのWindows 7上で動作しているときにのみロードされるのWindows 7でサポートされている機能が含まれているものを?私は本当に上記のようないくつかの種類の遅延バインディングを好むでしょう。

更新

私が実際に書いたものを読んでください。私ははっきりSHLoadLibraryFromItem私はDLLはをロードしたときに、アプリケーションが実際に単にアプリケーションのクラッシュWINDOWS 7に

を実行していることを確実に知っている限り呼ばないであることを最初の段落で述べました。

答えて

10

リンカが使われているすべてのAPI関数へのごモジュール内の参照を埋め込みます。 Windowsローダーが実行可能ファイルとそのモジュールを読み込むときには、コード内のすべての呼び出しを、API関数が実際に読み込まれるメモリ内の場所に「接続する」必要があります。それが見つからなければ、それは続かないでしょう。

LoadLibraryGetProcAddressを使用することは、この問題を回避するための「標準的な」方法です。

2つのDLLを使用しても、1つのアプリケーションの読み込みに失敗しても、まだ起動しないため、役立たない場合があります。これを回避するには、遅延ロードを使用し、新しいO/Sに依存するすべてのコードを別のモジュールに入れ、そのモジュールへのすべての呼び出しをWin32 SEH例外ハンドラでラップします(遅延ロード時にSEH例外が発生します)モジュールをロードできません)。利点は、関数ポインタの混乱なしに "自動"リンクを使用できることですが、例外処理はかなり厄介かもしれません。

This articleは少し説明し、これをきちんとまとめていく方法の例を示します。

+0

個々のシンボルだけを遅延ロードすることはできません。 (私はLinuxでELF実行可能ファイルでこれを行うことができたことに慣れています) –

+0

@Craig Ringer私はそうは思わない、リンカーへの遅延ロードパラメータはモジュールのリストです。技術的には、リンカはそれをかなり簡単に行うことができます。なぜなら、各関数のスタブを生成しているからです。しかし、それを実現する方法はないと思います。 –

+0

@Craig Ringerおそらく私はあなたの質問を誤解していました...もしDLLが存在していて、あなたが参照している関数の1つがそうでなければ、リンカによって生成された遅延ロードコードはそれぞれ 'GetProcAddress()'呼び出しを別々に試みるべきです。行方不明のものは例外を生成しますが、他のものはまだ動作します。 –

2

はなぜWindowsは、それが XP上で呼び出されていないにもかかわらず、 SHLoadLibraryFromItemを見つけるためにしようとしていますか?

Windowsは、呼び出しが行われたときではなく、アプリケーションがメモリにロードされたときに参照を解決します。これは、(リンカとの静的リンクとは対照的に)「動的リンク」と呼ばれますが、それは本当に動的ではありません。したがって、実行時に特定のメソッドが呼び出されるかどうかはわかりません。

関連する問題