Я смотрю на такие вопросы, как:
Мне кажется, это можно решить с помощью слабые символы. То есть нативный компонент может предоставлять такие символы, как rand
но украсить их __attribute__((weak))
, Если символ найден в другой библиотеке, например, во время выполнения, то слабо связанный символ не использоваться. С другой стороны, если символ отсутствует, то будет использоваться версия нативного компонента.
У меня проблемы с поиском информации для Android (слишком много посторонних шумов при поиске).
Я открыл один из моих примеров проектов Crypto ++ / JNI и добавил следующее в файл CPP. AutoSeededRandomPool
это просто объект генератора случайных чисел Crypto ++ (здесь нет ничего особенного или хитрого).
// CPP file
#ifdef __cplusplus
extern "C" {
#endif
int __attribute__((weak)) rand(void)
{
int r;
AutoSeededRandomPool& prng = GetPRNG();
prng.GenerateBlock(&r, sizeof(r));
return r;
}
#ifdef __cplusplus
}
#endif
Попытка скомпилировать это приводит к redefinition of int rand()
, Я также попробовал следующее:
// CPP file
#ifdef __cplusplus
extern "C" {
#endif
int rand(void) __attribute__((weak));
int random(void)
{
...
}
#ifdef __cplusplus
}
#endif
И движется int rand(void) __attribute__((weak));
в файл H выдает то же самое redefinition of int rand()
,
И я не получаю никаких ошибок или предупреждений о неизвестном атрибуте.
Я тоже вижу что __GXX_WEAK__
определяется для 1
в препроцессоре, но SUPPORTS_WEAK
является не определены, поэтому его смешанные сигналы (возможно, ошибка, похожая на определять GXX_WEAK до 0 при использовании -fno-слабого).
Я не уверен, что делаю что-то не так или испытываю что-то вроде константный и слабый атрибут с кодом C ++, или что-то другое.
Поддерживает ли Android слабые символы? Если так, то как их использовать.
Вот аналогичный вопрос переполнения стека, на который нет ответа:
Некоторые системные детали:
Android не поддерживает слабое переопределение символов.
В недавнем выпуске android-5.0.2_r1,
см. комментарий в строке 539 в linker.cpp исходный код
/*
*
* Notes on weak symbols:
* The ELF specs are ambigious about treatment of weak definitions in
* dynamic linking. Some systems return the first definition found
* and some the first non-weak definition. This is system dependent.
* Here we return the first definition found for simplicity.
*/
Этот комментарий существует с версии 2.2_r1 (которая находится в linker.c) до последней версии 5.0.2_r1
ТЛ; др; Android поддерживает слабые символы
Обратите внимание, что это не специфично для Android, это в равной степени верно для ld-linux.so/ld:
Это требует некоторого пояснения, потому что есть 2 случая, когда используются слабые символы:
(1) Для статических библиотек и объектных файлов можно определить несколько слабых символов, а правильный (самый сильный или первый) выбирается во время компиляции конечного объекта (.so или исполняемого файла).
(2) Для динамических библиотек слабые символы ведут себя так же, как символы по умолчанию, с одним исключением. Это означает, что не существует такой вещи, как слабое переопределение символов для разделяемых библиотек. Другими словами, во время перемещения / dlsym () будет возвращен первый найденный (GLOBAL) символ: слабый или по умолчанию.
Например (здесь мы предполагаем, что ни один из объектов не является -символическим, это еще одно исключение):
| main.executable <- слабое (слабое) определение foo ()
| -> lib1.so <- сильное (DEFAULT) определение foo ()
| -> lib2.so <- использует foo ()
lib2.so будет использовать реализацию foo () из main.executalbe, несмотря на то, что lib1.so экспортирует DEFAULT foo ().
Исключением является то, что символы WEAK могут оставаться неразрешенными во время процесса компоновки во время выполнения и приводить к нулевой ссылке в большинстве полезных случаев … когда в случае неразрешенного компоновщика во время выполнения символа DEFAULT происходит сбой.