我想通过JNI从我的Java应用程序中使用第三方共享库。
(我在Manjaro Linux上运行,目前使用命令行工具)
如果我不在www.example.com中创建第三方库的依赖项,我可以很好地构建和运行它myLib.so。
一旦我创建了一个从myLib.so到第三方库的依赖项,Java调用就会失败
java: symbol lookup error: myLib.so: undefined symbol: acOpenSystem
我已经尝试将库路径设置为库的位置,但仍然失败。
java -Djava.library.path=.:$ARENA_LIBS:$ARENALIBS2 MyClass
我确信有一些简单的东西我错过了,但我似乎不能从网络上占卜出答案。请帮帮我即使是一个链接到一个盲目明显的资源,我没有找到将是受欢迎的;- )
谢谢
编辑:这里是来源。HelloWorld -> Foo -> Bar Bar. c
#include <stdio.h>
void bar(void)
{
puts("\nHello, I am a shared library called BAR");
}
bar.h
#ifndef bar_h__
#define bar_h__
extern void bar(void);
#endif // bar_h_
食品c:
#include <jni.h>
#include <stdio.h>
#include "bar.h"
#include "HelloWorld.h"
// https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
void foo(void)
{
puts("\nHello, I am a shared library");
bar();
}
JNIEXPORT void JNICALL Java_HelloWorld_foo
(JNIEnv *, jobject) {
foo();
}
foo.h:
#ifndef foo_h__
#define foo_h__
extern void foo(void);
#endif // foo_h_
HelloWorld.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: foo
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_foo
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
HelloWorld.java:
import java.io.File;
class HelloWorld {
public static void main(String[] args) {
try {
File file = new File("libFoo.so");
String path = file.getAbsoluteFile().toPath().toString();
System.out.println("path = "+ path);
System.load(path);
System.out.println("Hello from java app"); // Display the string.
new HelloWorld().foo();
} catch (Exception e) {
e.printStackTrace();
}
}
private native void foo();
}
我的脚本文件:
#!/bin/sh
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
# compile foo
gcc -c -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -Wall -Werror -fpic foo.c
# link object into shared library
gcc -shared -o libFoo.so foo.o
# compile bar
gcc -c -Wall -Werror -fpic bar.c
# link object into shared library
gcc -shared -o libBar.so bar.o
LD_LIBRARY_PATH=::$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
gcc -L$SCRIPT_DIR -o test hello-world.c -lFoo -lBar
./test
LD_LIBRARY_PATH=$SCRIPT_DIR:$LD_LIBRARY_PATH
echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH"
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH
javac HelloWorld.java
javac -h . HelloWorld.java
java -Djava.library.path=. HelloWorld
为了完整起见,c可执行文件的源代码可以证明问题不在c代码中:
#include <stdio.h> // C Standard IO Header
#include "foo.h"
int main(int argc, char *argv[]) {
printf("Hello from executable");
foo();
}
c中的可执行文件运行正常,但java应用程序给出一个错误:
Hello from java app
Hello, I am a shared library
java: symbol lookup error: /mnt/data/singer/c/experiment/libFoo.so: undefined symbol: bar
java -version
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment Temurin-17.0.5+8 (build 17.0.5+8)
OpenJDK 64-Bit Server VM Temurin-17.0.5+8 (build 17.0.5+8, mixed mode, sharing)
gcc --version
gcc (GCC) 12.2.1 20230201
在Manjaro 22.1上运行
1条答案
按热度按时间vmdwslir1#
我想我现在已经让它工作了。我会把我的剧本留给后人: