linux - 在嵌入式 Linux 平台上将 libc 与 JNI 代码链接 (GuruPlug)

标签 linux linker java-native-interface libc

我正在尝试在嵌入式 Linux 平台(一台 GuruPlug 计算机)上编译一个简单的 JNI 应用程序,但由于某种原因它没有正确链接到 libc。我正在编译的 Java 程序称为 Test.java:

public class Test {
    static {
        System.loadLibrary("Test");
    }

    public static void main(String[] args) {
        new Test().printMessage();
    }

    public native void printMessage();
}

printMessage()的实现在Test.c中:

#include <jni.h>
#include <stdio.h>
#include "Test.h"

JNIEXPORT void JNICALL Java_Test_printMessage(JNIEnv *env, jobject obj)
{
    printf("Message 123...\n");
}

我在 bash shell 上使用以下命令编译 Test.c:

gcc -g -shared -static -lc -Wl,-soname,libTest.so -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ Test.c -o libTest.so

当我运行上述命令时,我收到错误消息“共享对象中不允许 R_ARM_TLS_LE32 重定位”。完整的错误信息是:

/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabi/4.4.5/../../../libc.a(dl-tsd.o)(.text+0x18): R_ARM_TLS_LE32 relocation not permitted in shared object

尽管出现错误信息,JNI .so 文件仍然是由编译器编写的,但是运行 Java 应用程序会出现以下错误信息:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/lib/jni/libTest.so: /usr/lib/jni/libTest.so: unexpected reloc type 0x03
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1750)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1675)
        at java.lang.Runtime.loadLibrary0(Runtime.java:840)
        at java.lang.System.loadLibrary(System.java:1047)
        at Test.<clinit>(Test.java:3)
Could not find the main class: Test. Program will exit.

有人知道如何解决这个问题吗?不可否认,上面的代码只是一个玩具示例,但我需要获得一个在这个平台上编译的真正的 JNI 库,而真正的 JNI 库依赖于 libc。我似乎无法解决将 libc 与 JNI 库链接的基本问题。任何建议将不胜感激。

谢谢!

最佳答案

gcc -g -shared -static -lc -Wl,-soname,libTest.so -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ Test.c -o libTest.so

上面的命令行有几个问题:

  • -shared-static 标志是互斥的,第二个覆盖第一个
  • 链接共享库时,您需要在大多数架构上使用-fPIC
  • -lc 放在错误的位置(应该跟在你的来源后面,而不是在它们之前),而且也不是必需的:gcc 会自动添加它
  • 您也不一定需要 -soname;这只是无用的困惑

正确的命令是:

gcc -g -shared -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux \
  Test.c -o libTest.so

关于linux - 在嵌入式 Linux 平台上将 libc 与 JNI 代码链接 (GuruPlug),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7958692/

相关文章:

gcc - 如何使用 gcc 工具链强制二进制文件中的函数顺序?

java - JNI native 接口(interface)和 JavaFX - NoClassDefFoundError

java - 在 linux 中使用 java 代码

python - CLIPSpy:获取 "No module name ' clips._clips'”导入剪辑

c++ - 构建 Tensorflow 调试时出错 LNK2019

android - 从 C++ 访问 Android 上的 GPS

java - 安卓 JNI OutOfMemoryError

c - gtk2 中已弃用的 gtk_list_new() 的替代方案?

linux - linux下与wifi接口(interface)绑定(bind)

gcc - AIX 5.3 (ld-xlc) 等效选项 Linux (ld-gcc) -rpath