【问题标题】:Different behavior of override weak function in shared library between OS X and AndroidOS X 和 Android 共享库中覆盖弱函数的不同行为
【发布时间】:2013-12-10 08:58:05
【问题描述】:

我在 OS X 和 Android 之间遇到了不同的行为:

  • 我的共享库中有一个弱函数foo
  • 我想用我的可执行文件中定义的强函数覆盖它。
  • 我希望被覆盖的也会影响库内的调用

结果:我在 OS X 上得到了预期的结果,但在 Android 上失败了。


这是我的测试项目:

文件:shared.h

void library_call_foo();
void __attribute__((weak)) foo();

文件:shared.c

#include "shared.h"
#include <stdio.h>

void library_call_foo()
{
    printf("shared library call foo -> ");
    foo();
}

void foo()
{
    printf("weak foo in library\n");
}

文件:main.c

#include <stdio.h>
#include <shared.h>

void foo()
{
    printf("strong foo in main\n");
}

int main()
{
    library_call_foo();
    printf("main call foo -> ");
    foo();
    return 0;
}

我在 OS X 使用命令编译并运行它:

clang -shared -fPIC -o libshared.so shared.c
clang -I. -L. -lshared -o test main.c
./test

按预期返回结果:

shared library call foo -> strong foo in main
main call foo -> strong foo in main

但是当我使用 NDK 工具链为 Android 编译它时,使用相同的命令:

arm-linux-androideabi-clang -shared -fPIC -o libshared.so shared.c
arm-linux-androideabi-clang -I. -L. -lshared -o test main.c

在设备上运行它,我得到了不同的结果:

shared library call foo -> weak foo in library
main call foo -> strong foo in main

为什么行为不同,我该如何解决?

【问题讨论】:

标签: android android-ndk cross-platform weak-linking


【解决方案1】:

Android 动态链接器实际上支持弱符号。问题是这个特殊情况是库是用 -Bsymbolic 编译的(检查这个运行“readelf -d libshared.so”)。

解决此问题的方法是在链接库时使用“-Wl,-shared”而不是“-shared”。

有关详细信息和解决方法,请参阅https://code.google.com/p/android/issues/detail?id=68956

【讨论】:

    【解决方案2】:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多