В Android-ndk, Как заставить _fini () вызываться при вызове dlclose ()? - PullRequest
1 голос
/ 10 июня 2019

Мы используем библиотеки C в нашем проекте Android-NDK. Мы используем dlopen () & dlclose () для работы с нашими библиотеками в Android NDK. Когда мы вызываем dlopen (), _init () библиотеки вызывается, как и ожидалось. Наоборот, когда мы закрываем библиотеку с помощью вызова dlclose (), функция _fini () не вызывается. Мы не хотим явно вызывать функцию _fini () после вызова API dlclose (). Я тестирую их на API 24.

Как и в Linux, две функции _init () и _fini () должны вызываться, когда мы вызываем dlopen () и dlclose () соответственно.

void func( ){
...
   int ret = -1;
   handle = dlopen( "mylib.so", RTLD_NOW | RTLD_GLOBAL );
   ret = dlclose( handle );    // dlclose() is returning 0.
...
}

void _init( ){
   log("dlopen is loading the library");
}

void _fini( ){
   log("dlclose is unloading the library");
}

Я также попытался изменить синтаксис _fini (), как показано ниже, но безуспешно.

void _fini() __attribute__((destructor));

Даже с атрибутом «деструктор», как и в предыдущей строке, _fini () не вызывается из dlclose ().

Поскольку функция _init () вызывается для dlopen (), я уверен, что _fini () также следует вызывать для dlclose (), поэтому я должен что-то упустить. Мы используем Android Studio для сборки apk. Может кто-нибудь, пожалуйста, помогите мне в этом. Заранее спасибо.

1 Ответ

1 голос
/ 13 июня 2019

Лучший совет, который я могу дать о dlclose, - никогда не использовать dlclose.

dlclose не предназначен для выполнения каких-либо действий, кроме информирования среды выполнения о том, что может выгрузить библиотеку;среда выполнения не должна ничего с этим делать.Для систем, в которых реализована выгрузка (включая Android), это не всегда возможно, потому что такие вещи, как atexit обработчики (или обработчики выхода потока и т. Д.) Не могут быть запущены, пока не завершится вся программа, поэтому каждый раз, когда библиотека регистрирует такой обработчикэто не может быть выгружено.Похоже, что так и есть.

Точный вариант использования может привести к изменению ответа, но для случаев, которые мы видели, такое поведение невозможно удалить (интерфейс подключаемого модуля, в котором ожидаются подключаемые модули)чтобы разгрузить, а затем перезагрузить со всеми сбросами их состояния), исправление заключается в добавлении явных функций Initialize() и ShutDown() в библиотеку.Они должны вызываться пользователем библиотеки, а не полагаться на dlopen / dlclose.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...