Выгрузить динамическую библиотеку нужно два вызова dlclose()?

У меня есть динамическая библиотека, которую я загружаю, используя dlopen() а затем выгрузить с помощью dlclose();

Если я не включаю какой-либо объективный код c dlopen() нужен один dlclose() вызов, который является ожидаемым поведением. Но когда я включаю любой целевой код c для цели, у меня возникает проблема, что мне нужно сделать два dlclose() звонки в загруженную библиотеку для выгрузки.

Это ожидаемое поведение? Как я могу это исправить?

1 ответ

Решение

Я понимаю, что вы используете dlopenне CFBundle или же NSBundle, Тем не менее, руководство по программированию загрузки кода говорит следующее:

В приложениях Какао, вы не должны использовать CFBundle подпрограммы для загрузки и выгрузки исполняемого кода, потому что CFBundle изначально не поддерживает среду выполнения Objective-C. NSBundle правильно загружает символы Objective C в систему времени выполнения, но нет способа выгрузить связки Какао после загрузки из-за ограничения времени выполнения.

и это:

Из-за ограничения в системе времени выполнения Objective C, NSBundle не может выгрузить исполняемый код.

Это заставляет меня подозревать, что когда вы загружаете вашу библиотеку, она регистрируется во время выполнения Objective C, и вызовы времени выполнения dlopen снова в библиотеке (или как-то увеличивает счетчик ссылок библиотеки).

Я искал исходный код среды выполнения Objective C и нашел это:

// 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 дважды вы должны ожидать, что случится что-то плохое.

Другие вопросы по тегам