如何在共享库中管理未定义的符号

时间:2013-01-28 05:25:26

标签: c gcc shared-libraries

我有一个共享库,其中包含未定义的符号

JNI_CREATEJavaVM

有没有办法可以包含外部依赖项或告诉编译器忽略符号?

2 个答案:

答案 0 :(得分:4)

是的,您可以告诉编译器忽略该符号。

来自man ld

- 未解决的符号=方法

确定如何处理未解析的符号。方法有四种可能的值:

   ignore-all
       Do not report any unresolved symbols.

   report-all
       Report all unresolved symbols.  This is the default.

   ignore-in-object-files
       Report unresolved symbols that are contained in shared
       libraries, but ignore them if they come from regular object files.

   ignore-in-shared-libs
       Report unresolved symbols that come from regular object
       files, but ignore them if they come from shared libraries.

答案 1 :(得分:3)

1)我认为(心灵感应模式)您正在尝试构建libdvm.so并破解Java NDK,这不会暴露JNI_CREATEJavaVM功能。不要这样做。去和谷歌为什么不,以及其他可能的解决方案。

2)由于您的问题听起来像“如何管理”,我会提出我最喜欢的方式来管理这些事情 - 通过引入假的弱定义。让我们走出去构建共享库,因为我们建立什么并不重要。考虑我们有一些带有代码的unexym.c文件:

int
main(void)
{
  JNI_CREATEJavaVM();
  return 0;
}

它会产生undefined reference to `JNI_CREATEJavaVM'错误。

让我们添加到链接模块fakeone.c与假弱存根:

#include "assert.h"

int  __attribute__((weak))
JNI_CREATEJavaVM(void)
{
  assert(0 == "stub JNI_CREATEJavaVM is not for call");
  return 0;
}

现在一切都链接正常,但是在存根调用中产生运行时断言

a.out: fakeone.c:6: JNI_CREATEJavaVM: Assertion `0 == "stub JNI_CREATEJavaVM is not for call"' failed

但为什么它很弱?因为有人认为有人将它与真正的JNI_CREATEJavaVM代码相关联。例如,试试goodone.c

#include "stdio.h"

int
JNI_CREATEJavaVM(void)
{
  printf("JNI_CREATEJavaVM Ok\n");
  return 0;
}

编译gcc undesym.c goodone.c fakeone.c 现在正确的定义会覆盖弱存根,您将收到正确的消息。

当然你必须尽量避免使用这种技术,但它帮了我几次。