我正在尝试在嵌入式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库链接的基本问题。任何建议都将不胜感激。
谢谢!
答案 0 :(得分:2)
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