0

我有一个未定义符号的共享库

JNI_CREATEJavaVM

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

4

2 回答 2

4

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

man ld,

--unresolved-symbols=方法

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

   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.
于 2013-01-28T08:09:50.240 回答
3

1)我认为(心灵感应模式开启)您正在尝试构建 libdvm.so 并围绕 Java NDK 进行破解,它不公开 JNI_CREATEJavaVM 函数。不要这样做。去谷歌搜索为什么不,还有其他可能的解决方案。

2)由于您的问题听起来像是“如何管理”,因此我将介绍我最喜欢的管理此类事情的方法-通过引入虚假的弱定义。让我们开始构建共享库,因为我们构建什么并不重要。考虑我们有一些带有代码的undesym.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 现在正确的定义覆盖弱存根,您将得到正确的消息。

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

于 2013-01-28T07:34:50.187 回答