none
DLLを呼び出すときのソリューションエクスプローラなどの「リンクの設定」について RRS feed

  • 質問

  •  

    初歩的な質問かもしれませんが、どうかご回答お願いいたします。

     会社と自宅でともにXPPCを使い、ともにVS2005をインストールしてあります。さて、C++のプログラムから既存DLL(自分が作ったものでなく、かつmicrosoft社製でない)を呼び出すプログラムを作ったところ、会社のPCでは動いたのですが、自宅のPCにコピーしたらうまく動きません(ただし、コンパイルエラーはありません)。

    ソースのLoadLibrary(“DLL”)で呼び出したところ、戻り値がNULLになってしまいます。自分では「リンクの設定」(この表現が妥当かわかりません)に問題があるのではないかと考えています。ちなみにこのプログラムは市販書籍および付録のCD-ROMにあるプログラムを元に作ったもので(DLLは同一のもの)、こちらも動くのですが「リンクの設定」が、自分の作ったものとは違います。

     自宅のPCでも動くようにするためにどうしたらいいでしょうか。自宅のPCで動かすこと自体が最終目的ではありません。製品化する際、お客様のPC上で確実に動く状態にしたいからです。そのためにも正しい「リンクの設定」について理解しておきたいと考えました。

    以下、「リンクの設定」について記します。

     

    1.会社の自分のプログラム(DLLが読み込める)

    DLLC++のプロジェクトファイル内にコピーし、ソリューショエクスプローラでプロジェクトに追加してあります。追加するとき表示された画面に従い、ビルドの新しい規則を追加するに「はい」を押しました。新しい規則名、ファイル名を設定し、C:\\IDE\newItemsの下にデータを保存しました。

    またDLLと同名のヘッダファイル(自分が作ったものでなく、かつmicrosoft社製でない)C++のプロジェクトファイル内にコピーし、ソリューショエクスプローラでプロジェクトに追加してあります。

    2.市販書籍のプログラム(DLLが読み込める)

     上記と同一のDLLとヘッダファイルがそれぞれC++のプロジェクトファイル内にコピーしてあります。ところがソリューショエクスプローラにはDLLもヘッダファイルも表示されていません。

    3.自宅の自分のプログラム(DLLが読み込めない)

     DLLとヘッダファイルを上記1,2のいずれも方法でも試みましたが、LoadLibrary(“DLL”)の戻り値がNULLになってしまいます。ただしコンパイルエラーはありません。

     

    2008年6月6日 7:27

回答

  • 通常、LoadLibraryを使ってDLLを使う場合、リンク設定の必要は無いはずです。

    リンクの設定を行うと言うことはLoadLibraryを使わずに実行ファイルに直接リンクする方法を

    使用する場合の話です。なのでLoadLibraryできない事とリンクの設定は関係無いと思います。

    基本的にLoadLibraryできないのは、対象のDLLがパスにもカレントフォルダにも見当たらなくて

    そもそも読み込めないとか、対象のDLLが他のDLLを内部でリンクしていてそっちのDLLが

    見つからなくて読み込めないとかそういう話だと思います。

     

    DLLを使用する場合、明示的なリンクと暗黙的なリンクの二種類があります。

    この二種類のリンク方法についてきちんと勉強される事をお勧めします。

    Web上で調べれば、色々出てくるはずです。

     

    2008年6月6日 8:18
  • DLL の依存関係は Dependency Walker でチェックできます。

    こちらも読んでみてください。

    http://msdn.microsoft.com/ja-jp/library/ms235265(VS.80).aspx

     

    2008年6月6日 9:02
  •  hibari さんからの引用

    3.自宅の自分のプログラム(DLLが読み込めない)

     DLLとヘッダファイルを上記1,2のいずれも方法でも試みましたが、LoadLibrary(“DLL”)の戻り値がNULLになってしまいます。ただしコンパイルエラーはありません。

    DLLに対するLoadLibraryは実行時に行われるわけですので、コンパイルエラーになることはあり得ません。

    動くかどうかはそのPC(環境)で実行するまで分からないのです。

     

    で、この場合の問題ですが、LoadLibraryで指定しているDLLが見つからないという可能性が考えられます。

    DLLの検索はアプリケーションと同じフォルダ、System32等いくつかの規則があります。

    (詳細:http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx

     

    適切な場所にそのDLLを配置(コピー)して下さい。

     

     

    ■リンカの設定で解決するタイプ、つまりlibファイルとリンクするパターン

    ・LoadLibraryは不要

    ・実行するときにDLLが見つからないと起動できません

    ・関数ポインタを意識することなく、単なる関数呼び出しで使用できる

     

    ■LoadLibraryのパターン

    ・LoadLibraryが必要

    ・実行するときにDLLが見つからない場合でも、LoadLibraryからNULLが帰ってくることで分かるため、ユーザに適切なエラーメッセージを出せる可能性がある

    ・GetProcAddressで関数のアドレスを取得して、その関数ポインタで関数を呼び出す必要がある

     

    2008年6月6日 14:27
    モデレータ
  • 回答はちゃんと読まれていますか?

     

    // The specified module could not be found.
    //
    #define ERROR_MOD_NOT_FOUND              126L

     

    DLLが見つからないのでしょう。

    先にも書きましたが、必要なのであれば配置を見直して下さい。

     

     Azulean さんからの引用

    で、この場合の問題ですが、LoadLibraryで指定しているDLLが見つからないという可能性が考えられます。

    DLLの検索はアプリケーションと同じフォルダ、System32等いくつかの規則があります。

    (詳細:http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx

     

    適切な場所にそのDLLを配置(コピー)して下さい。

     

    「英語はNG」として拒絶するのではなく、単語辞書片手に格闘しましょう。

    2008年6月8日 4:10
    モデレータ
  •  hibari さんからの引用

     

    GetLastErrorは126を返していました。指定されたモジュールが見つからないということでしょうか。

     

    VS2005でしたらメニューのツールにエラールックアップと言うのが有りませんか?

    確かこれでエラーコードと内容の確認が出来たと思いますけれど。

    これで調べたのであれば、そのままの意味と受け取って良いと思いますよ。

     

    LoadLibraryした時にどのようなルートでDLLが検索されるのかをちゃんと調べた方が良いと思います。

    そのルート上にDLLが存在しなければ、読み込まれませんから。

     

     

    2008年6月9日 3:15

すべての返信

  • LoadLibrary が失敗したとき、GetLastError は何を返していますか?

    2008年6月6日 7:52
  • 通常、LoadLibraryを使ってDLLを使う場合、リンク設定の必要は無いはずです。

    リンクの設定を行うと言うことはLoadLibraryを使わずに実行ファイルに直接リンクする方法を

    使用する場合の話です。なのでLoadLibraryできない事とリンクの設定は関係無いと思います。

    基本的にLoadLibraryできないのは、対象のDLLがパスにもカレントフォルダにも見当たらなくて

    そもそも読み込めないとか、対象のDLLが他のDLLを内部でリンクしていてそっちのDLLが

    見つからなくて読み込めないとかそういう話だと思います。

     

    DLLを使用する場合、明示的なリンクと暗黙的なリンクの二種類があります。

    この二種類のリンク方法についてきちんと勉強される事をお勧めします。

    Web上で調べれば、色々出てくるはずです。

     

    2008年6月6日 8:18
  • DLL の依存関係は Dependency Walker でチェックできます。

    こちらも読んでみてください。

    http://msdn.microsoft.com/ja-jp/library/ms235265(VS.80).aspx

     

    2008年6月6日 9:02
  •  hibari さんからの引用

    3.自宅の自分のプログラム(DLLが読み込めない)

     DLLとヘッダファイルを上記1,2のいずれも方法でも試みましたが、LoadLibrary(“DLL”)の戻り値がNULLになってしまいます。ただしコンパイルエラーはありません。

    DLLに対するLoadLibraryは実行時に行われるわけですので、コンパイルエラーになることはあり得ません。

    動くかどうかはそのPC(環境)で実行するまで分からないのです。

     

    で、この場合の問題ですが、LoadLibraryで指定しているDLLが見つからないという可能性が考えられます。

    DLLの検索はアプリケーションと同じフォルダ、System32等いくつかの規則があります。

    (詳細:http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx

     

    適切な場所にそのDLLを配置(コピー)して下さい。

     

     

    ■リンカの設定で解決するタイプ、つまりlibファイルとリンクするパターン

    ・LoadLibraryは不要

    ・実行するときにDLLが見つからないと起動できません

    ・関数ポインタを意識することなく、単なる関数呼び出しで使用できる

     

    ■LoadLibraryのパターン

    ・LoadLibraryが必要

    ・実行するときにDLLが見つからない場合でも、LoadLibraryからNULLが帰ってくることで分かるため、ユーザに適切なエラーメッセージを出せる可能性がある

    ・GetProcAddressで関数のアドレスを取得して、その関数ポインタで関数を呼び出す必要がある

     

    2008年6月6日 14:27
    モデレータ
  •  

    GetLastErrorは126を返していました。指定されたモジュールが見つからないということでしょうか。
    2008年6月8日 1:32
  • 回答はちゃんと読まれていますか?

     

    // The specified module could not be found.
    //
    #define ERROR_MOD_NOT_FOUND              126L

     

    DLLが見つからないのでしょう。

    先にも書きましたが、必要なのであれば配置を見直して下さい。

     

     Azulean さんからの引用

    で、この場合の問題ですが、LoadLibraryで指定しているDLLが見つからないという可能性が考えられます。

    DLLの検索はアプリケーションと同じフォルダ、System32等いくつかの規則があります。

    (詳細:http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx

     

    適切な場所にそのDLLを配置(コピー)して下さい。

     

    「英語はNG」として拒絶するのではなく、単語辞書片手に格闘しましょう。

    2008年6月8日 4:10
    モデレータ
  •  hibari さんからの引用

     

    GetLastErrorは126を返していました。指定されたモジュールが見つからないということでしょうか。

     

    VS2005でしたらメニューのツールにエラールックアップと言うのが有りませんか?

    確かこれでエラーコードと内容の確認が出来たと思いますけれど。

    これで調べたのであれば、そのままの意味と受け取って良いと思いますよ。

     

    LoadLibraryした時にどのようなルートでDLLが検索されるのかをちゃんと調べた方が良いと思います。

    そのルート上にDLLが存在しなければ、読み込まれませんから。

     

     

    2008年6月9日 3:15
  • こんにちは! 中川俊輔です。

     

    皆様、回答ありがとうございます。

     

    hibariさん、フォーラムのご利用ありがとうございます。

    その後いかがでしょうか?

    問題が解決していないようでしたら、また質問してみてください!

    勝手ながら有用な情報と思われる回答へ回答済みチェックをつけさせていただきました。

     

    回答済みチェックが付くことにより、有用な情報を探している方が情報を見つけやすくなります。
    有用な情報と思われる回答があった場合は、なるべく回答済みボタンを押してチェックを付けてください。

    hibariさんはチェックを解除することもできますので、ご確認ください。

     

    それでは!

    2008年6月25日 10:03