ここから本文です

VisualStudioでビルドして実行するが、DLLが見つからないエラーになる

ama********さん

2012/3/1722:41:16

VisualStudioでビルドして実行するが、DLLが見つからないエラーになる

OpenCVで画像処理をするプログラムを作成中ですが、

ネイティブのC++のライブラリを.libで出力し、
C++/CLIでその.libを読み込みラッピングして.dllにして出力し、
C#でその.dllを読み込んでつくっています。

.lib, .dll も正常に出力されC#のプロジェクトも含めてビルドが通ります。
また最終的な.exeファイルの出力と共にそのディレクトリに.dllがコピーされています。

ビルドまで正常ですが、実行した際に.dllにアクセスするところでdllが見つからないというエラーが起こります。


参照は.exeファイルと同じディレクトリにdllをコピーしてきているように正常に思えますが、
こうしたエラーについて教えて頂けないでしょうか?

補足丁寧に答えていただきありがとうございます。
どうやらDLLのパス等の設定ではなくDLLの持っている関数自体に問題が有りそうです。

確認しながら作りなおしていたのですが、その過程ではDLLの内容を実行出来ました。
しかし、自身のない構造体配列をやりとりするメソッドを使用した途端に、DLLが見つかりません、というエラーが出ました。

閲覧数:
73,860
回答数:
2
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

abi********さん

編集あり2012/3/2004:29:10

[Win32 dll の場合]

dll を置く場所は、exeファイルと同じ場所とは限らないです。
dll を呼ぶ側のプログラムにとってのカレントディレクトリに置きます。

例えば、まだソフトの開発中の場合は、Visual Studio の管理下で開発対象のプログラムを実行します(デバッグで実行するので)。
確かVisual Studio のバージョンの違いによって、Debugフォルダ(すなわち、exeファイルと同じ場所)の下が呼び出し元のカレントディレクトリの場合もあるし、プロジェクトファイルが置かれているフォルダがカレントディレクトリの場合もありました。
よって、私は、どちらがカレントディレクトリなのか確かめるのは面倒くさいので、Debugフォルダと、プロジェクトファイルが置かれている場所の両方にdll をコピーしています。




取りあえず、Windows のシステムフォルダ(Windows自体のdll が沢山置かれている場所)に、該当の dll を置いてみて下さい。
呼び出し元のカレントディレクトリ以外では、Windows のシステムフォルダでも、呼び出し元のプログラムが dll を認識可能になります。
これで該当エラーにならなくなったら、質問で言われているように dll の置き場所の問題です。
もしも前述のカレントディレクトリの場所がわからなくても、Windows のシステムフォルダに置けば良いです。
(Windows のシステムフォルダの場合は、使わなくなった dll がたまってしまう可能性がありますので、呼び出し元のカレントディレクトリのほうが良いのですが)





[COM 形式のdll の場合]

上記のWin32 dll では、dll の置き場所が、上記の通りに限られてしまいます。
そこで、COMの場合では、どこのディレクトリに置いても構わない仕様になりました。
(COMは、Win32 時代の後のマイクロソフトのテクノロジーで、ActiveX や ATL や DirectX等は、COM形式です)
dll の場所をレジストリに登録するので、呼び出し元のプログラムは、dll の場所を認識することが可能になります。
しかし、逆に言えば、COM 形式の dll の場合は、必ずdll の場所をレジストリ登録する必要があります。
レジストリの登録方法は、検索エンジン(Google、Yahoo! 等)で、「COM」 と 「レジストリ」 と 「登録」のキーワードで検索して下さい。



[備考: マネージコードのdll]

質問は、ネイティブでの dll でのトラブルなので、上記の通り、「Win32 dll」 と 「COM形式のdll」の説明としました。
なお、上記までの説明で、「では、.NET形式(C#等)の dll は、どのような管理になったのか」と疑問に思うかも知れませんので、備考として下記に説明します。

ところで、COM形式では、レジストリ登録で便利になりましたが、その反面、dll地獄のトラブルが問題になってしまいました。
すなわち、他者が作った dll と、エクスポート名(dll が外部公開している機能等の名前)が、同じの場合のトラブルです。
バージョンアップの場合も、旧dll と 新dll のエクスポート名が、かち合ってしまうので、トラブルになります。
よって、.NET形式(C#等)の dll では、レジストリ登録をするやり方はやめて、dll は呼び出し元のプログラムが管理するやり方に戻りました。

ただし、もちろん、Win32 dll の場合とは、異なる面もあるようです。
例えば、.NET で作った dll を、COMで作るプログラムから利用することが可能です(すなわち、COM に公開する設定がある)。
この場合では、.NET で作った dll でも、レジストリ登録をする必要があります。
あくまでも仕組みに関する予備知識の話しですので、.NET 形式の dll のほうも、何かトラブルがあるようでしたら、改めて質問を出し直したほうが良いと思います。
なお、再質問を出す場合は、トラブルを起こしているdll の種類を記載するほうが良いと思います。
上記までの説明の通り、dll の種類によって、性質が異なりますので。





[追記]

なお、自分で作った dll ではない場合は、どの種類の dll か不明ですので、下記を参考にして下さい。

ネイティブ(C++)の dll ならば、有名なライブラリならば、だいたいCOM 形式の場合が多いです。
Win32 dll のほうは、自分で利用する簡単なライブラリならば、Win32 dll で作ることもあります。Win32 dll は、手軽に取り扱えるので。
また、COM テクノロジーを勉強するのは、結構大変ですので、まだ勉強していない人は、Win32 dll で作ることもあります。

どうしてもわからない場合は、結局 前述のように、システムフォルダに置いてみたりして、実際に確認するしかないです。
なお、他者が作ったCOM の dll の場合は、そのCOM形式のdll のインストーラーで、作者がレジストリ登録をする仕組みを作っています。普通は。
(すなわち、そのCOM形式のライブラリを、そのインストーラーでインストールすれば、レジストリ登録されます)





[補足の件]

多量データー(画像等)を扱っているように感じますが。(余白無)

この質問は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜1件/1件中

liv********さん

2012/3/1822:11:03

dll が参照する dll を読み込むことができないのかも。
Dependency Walker などで調べてみるといいよ。

http://www.dependencywalker.com/

あわせて知りたい

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる