我一直在寻找类似的问题:
在我看来,这可以通过weak symbols来解决。也就是说,本机组件可以提供rand
之类的符号,但可以使用__attribute__((weak))
来装饰它们。如果符号在另一个库中找到,例如标准运行时,则弱链接符号将不。另一方面,如果缺少符号,则将使用本机组件的版本。
我无法在Android上找到有关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
未定义,因此其混合信号(可能是错误,类似于Define GXX_WEAK to 0 when using -fno-weak)。
我不确定我是做错了什么,或者遇到类似const and weak attribute with c++ code之类的东西,或其他什么。
Android是否支持弱符号?如果是这样,那么如何使用它们。
这里有一个类似的Stack Overflow问题没有答案:
一些系统细节:
答案 0 :(得分:2)
TL;博士; Android确实支持弱符号
请注意,这不是特定于Android的,对于ld-linux.so/ld同样如此:
这需要一些澄清,因为有两种情况使用弱符号:
(1)对于静态库和目标文件,可以定义多个弱符号,并在编译时链接最终对象(.so或可执行文件)时选择正确的符号(最强或符号)。
(2)对于动态库,弱符号的行为与默认符号相同,只有一个例外。这意味着共享库没有弱符号覆盖这样的东西。换句话说,在重定位/ dlsym()期间,将返回第一个找到的(GLOBAL)符号:weak或default。
例如(这里我们假设没有任何对象是-Bsymbolic,这是另一个例外):
| main.executable< - 弱(WEAK)定义foo()
| - > lib1.so< - 强(DEFAULT)foo()的定义
| - > lib2.so< - 使用foo()
lib2.so将使用main.executalbe的foo()实现,尽管lib1.so导出DEFAULT foo()的速度很快。
例外情况是允许WEAK符号在运行时链接过程中保持未解析,并在大多数有用的情况下导致空引用...在未解析的情况下,DEFAULT符号运行时链接器失败。
答案 1 :(得分:1)
Android不支持弱符号覆盖。
在最近发布的android-5.0.2_r1中, 请参阅linker.cpp源代码
中第539行的评论/*
*
* 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