2012-01-09 10 views
7

私はdlopen()を使ってロードし、次にdlclose()を使ってアンロードする動的ライブラリを持っています。アンロードダイナミックライブラリには2つのdlclose()呼び出しが必要ですか?

目的のCコードを含めないと、dlopen()には、期待される動作であるdlclose()という呼び出しが1つ必要です。しかし、目的とする目的のCコードを含めると、アンロードするためにロードされたライブラリへの呼び出しを2回行う必要があるという問題があります。

これは予期した動作ですか?どうすれば修正できますか?

+0

あなたのライブラリが隠された形で 'dlopen'されていないことを確かめていますか?あるいはバグかもしれない。メモリリーク - は 'dlopen'-edハンドルの近くでメモリを上書きしていますか? –

+0

dlopenは、ライブラリハンドルの参照カウントを保持します。 dlopenを2回実行すると、ライブラリをアンロードするために2つのdlclose()が必要になります。 obj-Cコードをインクルードする場合、ダイナミックライブラリが必要なのでしょうか?あなたのプログラムを実行すると、最初のdlopenが実行される可能性があります。 – Finslicer

+0

はい、私はそのdlopenedが2回はないと確信しています。あなたはdlopenで簡単なプログラムを試してみることができ、dlcloseには目的のCコードを持つ動的ライブラリを使うことができます。 – MacGeek

答えて

26

CFBundleまたはNSBundleではなく、dlopenを使用しています。それにも関わらず、Code Loading Programming Topicsマニュアルは、これは言う:CFBundleはネイティブのObjective-Cランタイムをサポートしていないので、Cocoaアプリケーションで

、あなたは、実行可能コードをロードし、アンロードするCFBundleルーチンを使用しないでください。 NSBundleはObjective-Cシンボルをランタイムシステムに正しくロードしますが、実行時の制限のために一度ロードされたCocoaバンドルをアンロードする方法はありません。

この理由:Objective-Cランタイムシステムにおける制限の

は、 NSBundleが実行可能なコードをアンロードすることができません。

これは私はあなたがあなたのライブラリーをロードするとき、それはObjective-Cランタイムに自身を登録し、ランタイムは再びライブラリにdlopenを呼び出します(または何らかの方法でライブラリの参照カウントを増加)ことを疑うことができます。

私はObjective-Cランタイムのソースコードを検索し、thisが見つかりました:

// dylibs are not allowed to unload 
// ...except those with image_info and nothing else (5359412) 
if (result->mhdr->filetype == MH_DYLIB && _hasObjcContents(result)) { 
    dlopen(result->os.dl_info.dli_fname, RTLD_NOLOAD); 
} 

そうです、Objective-Cランタイムは、具体的にアンロードされるのを防ぐために、あなたのライブラリーにdlopenを呼びかけています。あなたが不正行為をしてdlcloseを2回呼び出すと、悪いことが起こると予想するべきです。

+0

+1すばらしい答え! – Till

関連する問題