在嵌入式 Linux 平台上将 libc 与 JNI 代码链接 (GuruPlug)
我正在尝试在嵌入式 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 库链接的基本问题。任何建议将不胜感激。
谢谢!
I'm trying to compile a simple JNI application on an embedded Linux platform (a GuruPlug computer), but for some reason it's not linking to libc properly. The Java program I'm compiling is called Test.java:
public class Test {
static {
System.loadLibrary("Test");
}
public static void main(String[] args) {
new Test().printMessage();
}
public native void printMessage();
}
The implementation of printMessage() is in 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");
}
I'm compiling Test.c with the following command on a bash shell:
gcc -g -shared -static -lc -Wl,-soname,libTest.so -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ Test.c -o libTest.so
When I run the above command, I get the error message "R_ARM_TLS_LE32 relocation not permitted in shared object". The full error message is:
/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
Despite the error message, the JNI .so file is still written by the compiler, but running the Java application gives the following error message:
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.
Does anybody have any idea how to go about fixing this? Admittedly, the above code is a toy example, but I need to get a real JNI library compiling on this platform, and the real JNI library depends on libc. I can't seem to solve this basic issue of linking libc with a JNI library. Any suggestions would be greatly appreciated.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
上面的命令行有几个问题:
-shared
和-static
标志是互斥的,-fPIC
在大多数体系结构上,-lc
位于错误的位置(应该在您的源代码之后,而不是在它们之前),并且无论如何都没有必要:gcc 会自动添加-soname
;这只是无用的混乱正确的命令是:
There are several problems with the command line above:
-shared
and-static
flags are mutually exclusive, and the second overrides the first-fPIC
on most architectures-lc
is in the wrong place (should follow your sources, not precede them), and is not necessary anyway: gcc will add it automatically-soname
either; it's just useless clutterThe correct command then is: