C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

DLL関数の寿命とロード方法

[トピック内 16 記事 (1 - 16 表示)]  << 0 >>

■83538 / inTopicNo.1)  DLL関数の寿命とロード方法
  
□投稿者/ 我孫子 (1回)-(2017/03/27(Mon) 16:03:04)

分類:[.NET 全般] 

環境:Windows10,Visual studio15 C++

DLLはロード時間かかるので静的LIBより実行時間がリアルタイムにならず、
遅いとも思われると聞いております。

ただ、EXE起動時点でDLL中の関数が一度ロードしてそれから
ずっと使えるならまだ良いと思いますが、どうでしょうか。
即ち、DLL関数の寿命はいつからいつまででしょうか。

それから、DLL関数のロードするためのコードプログラムの中で用意しなければならないのでしょうか、
それとも適当なタイミングでOSが自動にロードしてくれるのでしょうか。

引用返信 編集キー/
■83539 / inTopicNo.2)  Re[1]: DLL関数の寿命とロード方法
□投稿者/ 774RR (495回)-(2017/03/27(Mon) 16:28:46)
.NET 一般 で C++ だと話が発散するが native の話がしたいのか manage の話がしたいのか、どっちだろう?

静的 LIB なんて用語が出てきているので C++ つまり native の話であると読むことにする。
すると DLL 内部関数を使うには2通りの手法があって
・インポートライブラリ *.lib を静的リンクして使う
・ LoadLibrary + GetProcAddress して使う

前者なら EXE を起動したときに一緒に読み込まれ EXE 終了と同時に開放されると考えてよいっす。
> DLL 関数の寿命
は EXE と同じ。
> DLLはロード時間かかる
EXE 起動時にこのロード時間がかかるわけで、実行中に突然ロードされたりはしない、と考えてよい。

(真に同時にロードされるかどうかは OS のご機嫌というかメモリ使用量というか次第)
(まあそれを言うなら静的ライブラリを使っていても pageout されることはあるわけで話は同じ)

> DLL関数のロードするためのコードプログラムの中で用意
というのは後者の LoadLibrary の話。この場合 FreeLibrary するまで DLL を使うことができる。
このロード時間がクリティカルに効くようなコードを書いてるとしたら、設計と言うか実装が間違ってる。

セキュリティアップデート等のことを考えるとオイラ個人としては DLL のほうが良いと思うぞ。
静的 LIB にするといろいろ更新があったとき話が厄介になる。

引用返信 編集キー/
■83544 / inTopicNo.3)  Re[2]: DLL関数の寿命とロード方法
□投稿者/ 我孫子 (2回)-(2017/03/27(Mon) 18:28:52)
774RR さん
早速お返事ありがとうございます。

ご指摘の通り、.NETとは関係ないと思いますーーーー選択ジャンルが間違ってごめんなさい!

以前VBでDLLを使う時に、DLLの宣言やロード手続きをしなければならない記憶があります。
面倒くさかった。

Visual studio15 C++で開発する場合もそういうコードが自分で組まなければならないでしょうか。

そして他人のOpencvを利用するサンプル関数を見る限り、DLL関数を利用するには余分のコードは一切ないようです。
ちなみに、OpencvはDLL関数しか提供しないのです。静的なlibの形で利用できません。
またよろしくお願いいたします。


引用返信 編集キー/
■83545 / inTopicNo.4)  Re[3]: DLL関数の寿命とロード方法
□投稿者/ 774RR (497回)-(2017/03/27(Mon) 19:36:03)
微妙に何を聞きたいのかわからないけど
opencv を Visual C++ から使うのなら「インポートライブラリ」の設定を行うのがよく使う手順だろう。
そこだけ設定しとけば、あとはほぼ何も考えなくてもいい。

http://www.buildinsider.net/small/opencv/004

引用返信 編集キー/
■83557 / inTopicNo.5)  Re[4]: DLL関数の寿命とロード方法
□投稿者/ 我孫子 (3回)-(2017/03/28(Tue) 08:55:09)

774RR 様

お世話になっております。

下記の2点に理解できていません。ご教授いただければ幸いです。

>> DLL 内部関数を使うには2通りの手法があって
>> ・インポートライブラリ *.lib を静的リンクして使う
Q1: DLLを静的なLIBとして利用可能ということでしょうか。
  これはちょっと意外で、非常に興味を持っておりますので、
  DLLを静的なLIBとして利用する仕方を教えていただけませんか。
  (Visual studio C++環境で)
  要はOpencvのような動的なDLLしか提供されていないライブラリーを静的なLIBとして利用したいのです。
  -----ターゲットPCの環境設定を簡単にするために。

>> 後者の LoadLibrary の話
私はVBからDLLを利用した経験しかなく、確かにDLLの宣言とloadをプログラマーがコーディングしなければならないのです。

Q2: 宣言の部分がIDEに設定によって省けるかもしれませんが、
  各DLL関数のloadのタイミングもC++のほうは自動的にやってくれるのでしょうか。


宜しくお願い致します。






引用返信 編集キー/
■83558 / inTopicNo.6)  Re[5]: DLL関数の寿命とロード方法
□投稿者/ 774RR (500回)-(2017/03/28(Tue) 09:40:05)
インポートライブラリってのは EXE 起動時に必要な DLL を読み込むことを Windows に指示するためのもの。

例:インポートライブラリ winmm.lib 中には
timeGetTime() という関数は、実体が _timeGetTime@0 という名前で winmm.dll 中にあるよ
という情報だけが書かれている。

A1. DLL を静的にリンクするなんてできないよ。
Windows 標準でない DLL はインストーラで配布する必要がある。

A2. インポートライブラリを使ったら DLL のロードタイミングは EXE 起動時。
起動時点で DLL が見つからなかったら、そもそも EXE 起動が失敗する。

引用返信 編集キー/
■83561 / inTopicNo.7)  Re[6]: DLL関数の寿命とロード方法
□投稿者/ Jitta (281回)-(2017/03/28(Tue) 10:51:05)
> そして他人のOpencvを利用するサンプル関数を見る限り、DLL関数を利用するには余分のコードは一切ないようです。

手元のOpenCVのbuildディレクトリには、libというディレクトリにがあるのだが。
どの様に導入しましたか?
引用返信 編集キー/
■83566 / inTopicNo.8)  Re[7]: DLL関数の寿命とロード方法
□投稿者/ 我孫子 (4回)-(2017/03/28(Tue) 13:15:06)

>>A2. インポートライブラリを使ったら DLL のロードタイミングは EXE 起動時。
起動時点で DLL が見つからなかったら、そもそも EXE 起動が失敗する。

これは概念的に可笑しく思いたいですね。
だって、動的なライブラリというのは「必要な時」にのみロードされると理解しておりますが。
大きなアプリケーションの場合、たくさんDLLに関わるとします。
当然、実行過程において、条件分岐によって、全然コールされないDLL関数があります。
こんなDLLやDLL関数もEXE実行時点でとにかく全部ロードされるのは可笑しいではない?
---------というか、少なくともDLLのメリットは随分減るような気がします。




> 手元のOpenCVのbuildディレクトリには、libというディレクトリにがあるのだが。
> どの様に導入しましたか?


それは自分のもあります。
それは「静的な」LIBでサンプルコードが皆それを使っているので、DLLロード文がなくなると思えば、

じゃー、Opencvの「動的な」DLLを利用してコーディングする場合はどうすれば良いのでしょうか。


またご指導いただければ幸いです。








引用返信 編集キー/
■83569 / inTopicNo.9)  Re[8]: DLL関数の寿命とロード方法
□投稿者/ 774RR (501回)-(2017/03/28(Tue) 14:15:25)
普通の EXE の中にだって分岐等によってぜんぜん実行されないコードがあるのは同じ。
それは無駄だとは思わないの?
起動時に DLL の有無チェックが行われ、無いときはそもそも実行できないほうが安全方向だろう。
文書を保存しようとしたらそこで初めて DLL がありませんから保存できません、
なんてエラーになったらユーザーは怒り心頭だと思う。

同一 DLL は複数のプロセスで仮想記憶域を共有する構造なのでメモリの無駄にはなってないし
仮想記憶機構は今アクティブに使っていない関数や変数をワーキングセットの外に追い出すだろうし、
> 必要な時
にだけ EXE の該当部や DLL の該当部がワーキングセットにロードされるのだから
オイラはこの機構を無駄とは思わない(むしろ安全方向に振ってあって好ましいと思う)

我孫子さん的な意味で「動的に」ロードしたいのなら手で LoadLibrary/FreeLibrary を書くと良い。
手間なのでオイラならあまりやりたくないけど。メリットも薄いし・・・

引用返信 編集キー/
■83573 / inTopicNo.10)  Re[9]: DLL関数の寿命とロード方法
□投稿者/ 我孫子 (5回)-(2017/03/29(Wed) 08:47:30)

774RR さん
お世話になっております

奥深い面白い技術なので、もう少し理解したいですが。

> 我孫子さん的な意味で「動的に」ロードしたいのなら手で LoadLibrary/FreeLibrary を書くと良い。
> 手間なのでオイラならあまりやりたくないけど。メリットも薄いし・・・


LoadLibrary/FreeLibraryというのは、MS世界(VC++)の関数で、標準CやC++ではどうすれば良いのでしょうか。
それから、インポートライブラリーがあくまでもコンパイラーに関数名前「解決法」を与えるためのファイルで、
関数本体がDLLにあると思います。
やはり普通のCやC++のコンパイラーに LoadLibraryのようなコードが自動挿入されるのではと推測ですが、
そうであれば、なぜEXEが実行する瞬間にありとあらゆるDLLをメモリに一斉ロードする必要でしょうか。


また宜しくお願いします。




引用返信 編集キー/
■83575 / inTopicNo.11)  Re[10]: DLL関数の寿命とロード方法
□投稿者/ 774RR (502回)-(2017/03/29(Wed) 09:32:27)
> 標準CやC++ではどうすれば良いのでしょうか。
標準 C とは ISO/IEC 9899 標準 C++ とは ISO/IEC 14882 のこと?
ならば言語規格書はそういう詳細は一切何も決めていない。
「プログラム」がファイルで提供されるとも書かれていない
(組み込みの世界ではファイルという概念自体が無いことがある)

POSIX の世界なら dlopen() とかが存在する。

> なぜEXEが実行する瞬間にありとあらゆるDLLをメモリに一斉ロードする必要でしょうか。
「ありとあらゆる」ものをロードするわけが無いぢゃん。使ってないものはロードしない。
理由の1つは既に書いたのでくりかえさない。
別の理由は「 DLL があってもメモリが足らないとか別の理由でロードできないことがある」からだ。

malloc() を、失敗するまでひたすら繰り返してメモリを浪費した状態で LoadLibrary すると失敗する。
そうなると 83569 のような状況に陥って話にならない。
あらかじめロードしておけば問題ないってことで。

引用返信 編集キー/
■83577 / inTopicNo.12)  Re[11]: DLL関数の寿命とロード方法
□投稿者/ Jitta (282回)-(2017/03/29(Wed) 10:18:09)
ちょっと、何を聞きたいのか、わからない。
とりあえず、Windows向けの開発を始めるけど、
後々Linuxも対象に含める?
で、コードを共通にしておきたいとか?

OpenCV使うことが前提で、
WindowsとLinuxで、ってんなら、
GUIにはQt、言語はpythonなら、
そのまま両方に使えるんじゃないの?

質問の前提って結構重要なんだけど、
たいていの場合、省かれる。
最終目標が何で、
どういう過程があって質問に至ったのでしょうか。
引用返信 編集キー/
■83578 / inTopicNo.13)  Re[1]: DLL関数の寿命とロード方法
□投稿者/ Jitta (283回)-(2017/03/29(Wed) 10:37:07)
No83538 (我孫子 さん) に返信
移動中で入力環境が貧弱なので、チビチビ返して見る。

> DLLはロード時間かかるので静的LIBより実行時間がリアルタイムにならず、
> 遅いとも思われると聞いております。
> ただ、EXE起動時点でDLL中の関数が一度ロードしてそれから
> ずっと使えるならまだ良いと思いますが、どうでしょうか。
> 即ち、DLL関数の寿命はいつからいつまででしょうか。

計測を、どの様にするかによる。
DLLの大きさやその時のIO処理状況に依存するが、1秒以内で終わる。
その他の時間と比較して、そんなに大きなウェイトを占めるのか。
まずは測定の方法を決め、実際に測ってみなければなんとも言えない。


> それから、DLL関数のロードするためのコードプログラムの中で用意しなければならないのでしょうか、
> それとも適当なタイミングでOSが自動にロードしてくれるのでしょうか。

DLLを使用する方法はいくつかあって、
1)完全に開発者が制御する方法
2)静的ライブラリに1)の方法を仕込む
がある。DLLプロジェクトの設定により、2)の静的ライブラリを開発者がコードを書くことなく作れる。
2)の方法だと、静的ライブラリをリンクするが、実行時にはDLLが必要。
OpenCVの静的ライブラリは、2)だと思っている。(確認していない)
1)の方法を取るなら、「DLL関数のロードするためのコードプログラムの中で用意しなければならない」。
自分で書くので、好きな時にリリースできる。
2)の方法なら、「OSが自動的にロードしてくれる」。
また、この場合、プログラム終了までリリースしない。
引用返信 編集キー/
■83579 / inTopicNo.14)  Re[8]: DLL関数の寿命とロード方法
□投稿者/ Jitta (284回)-(2017/03/29(Wed) 10:48:38)
No83566 (我孫子 さん) に返信
>>手元のOpenCVのbuildディレクトリには、libというディレクトリにがあるのだが。
>>どの様に導入しましたか?
>
>
> それは自分のもあります。
> それは「静的な」LIBでサンプルコードが皆それを使っているので、DLLロード文がなくなると思えば、
>
> じゃー、Opencvの「動的な」DLLを利用してコーディングする場合はどうすれば良いのでしょうか。

ここがまたわからない。
LoadLibrary関数やGetProcAddress 関数の使い方を聞いてる?
静的なlibをリンクしているが、
実行時にDLLがないと起動できないので、
前の投稿の2)と認識しています。
つまり、libをリンクすれば自分でライブラリをロードしたり
プロセスのアドレスを探す必要はないが、
実行時にDLLが必要である、と。

で、何をしようとして、
何を調べてどんな結果を得て、
どう考えたための質問なのでしょうか。
引用返信 編集キー/
■83580 / inTopicNo.15)  Re[8]: DLL関数の寿命とロード方法
□投稿者/ 魔界の仮面弁士 (1226回)-(2017/03/29(Wed) 17:05:20)
No83566 (我孫子 さん) に返信
> それは「静的な」LIBでサンプルコードが皆それを使っているので、DLLロード文がなくなると思えば、

『インポート ライブラリ』としての LIB と
『静的リンクライブラリ』としての LIB のどちらの意味でしょうか。


OpenCV 3.0 までは、動的/静的両方のリンクライブラリが同梱されていたようですが、
OpenCV 3.1 からは DLL のみに変更されているようです。


静的リンクライブラリとしての.lib の場合は、
実装部は EXE 内に埋め込まれ、外部 .dll を必要としない。
.a と .so の場合も同様の関係。


一方インポート ライブラリとしての .lib は、DLL の呼び出しを助けるもので、
.lib は宣言部、実装部は .dll にあるもの。下記の URL においては、
「暗黙的なリンクによる方法」という書き方をしていますね。
http://exlight.net/devel/windows/dll/windll.html


宣言部の .lib が無くても、.dll を呼ぶことはできるわけで、
それが上記の URL でいうところの「明示的リンクによる方法」。

既に提示されているように、Windows の世界で言うところの
LoadLibrary + GetProcAddress + FreeLibrary であり、
POSIX での dlopen + dlsym + dlclose ですよね。
C# だとさらに Marshal.GetDelegateForFunctionPointer を使ったりしますが。
https://beatsync.net/bayside/memo/log20060602.html


で、OpenCV を使うことが主目的のアプリなら、そのまま暗黙的リンクで実装すれば良く。
OpenCV が無くても動作するアプリとして実装したいのであれば、DLL を
明示的リンクで呼び出すように実装すればよいのでは無いでしょうか。
引用返信 編集キー/
■83616 / inTopicNo.16)  Re[9]: DLL関数の寿命とロード方法
□投稿者/ Jitta (286回)-(2017/03/30(Thu) 20:20:26)
No83580 (魔界の仮面弁士 さん) に返信
>
> OpenCV 3.0 までは、動的/静的両方のリンクライブラリが同梱されていたようですが、
> OpenCV 3.1 からは DLL のみに変更されているようです。
>
なるほど。
私はコードからCMakeで構築しているので、VSでビルドするだけの方はわかりませんでした。



EiganやTBBを使えば若干速くなるようですよ。
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ