使用JNI加载动态C共享库,JNI还加载另一个共享库
在JavaEclipse(Linux)上使用JNI,我首先加载一个名为的动态共享库。 到目前为止一切进展顺利。 问题在于,first.so还加载了一个名为second.so的动态库 运行该程序时,我收到许多关于秒内符号的“未定义符号”错误。因此 似乎使用JNI加载的库无法在运行时加载其他C库,因为我们处于Java环境中。我的假设正确吗? 我需要特殊的编译标志来编译第一个.so库,还是需要特殊的参数来告诉eclipse它将在运行时加载.so 提前谢谢 似乎使用JNI加载的库无法在运行时加载其他C库,因为我们处于Java环境中。我的假设正确吗 没有使用JNI加载动态C共享库,JNI还加载另一个共享库,c,linux,eclipse,java-native-interface,shared-libraries,C,Linux,Eclipse,Java Native Interface,Shared Libraries,在JavaEclipse(Linux)上使用JNI,我首先加载一个名为的动态共享库。 到目前为止一切进展顺利。 问题在于,first.so还加载了一个名为second.so的动态库 运行该程序时,我收到许多关于秒内符号的“未定义符号”错误。因此 似乎使用JNI加载的库无法在运行时加载其他C库,因为我们处于Java环境中。我的假设正确吗? 我需要特殊的编译标志来编译第一个.so库,还是需要特殊的参数来告诉eclipse它将在运行时加载.so 提前谢谢 似乎使用JNI加载的库无法在运行时加载其他C库
libfirst.so
如何使用libsecond.so
?它是链接的依赖项,还是由dlopen
加载的
我发现类似于:
static {
System.loadLibrary("second");
System.loadLibrary("first");
}
在使用JNI的类中通常是有效的
编辑:现在我知道你是如何加载libsecond的了。所以这对我来说很有效:
Test.java
public class Test {
public static void main (String args[]) {
test();
}
private native static void test();
static {
System.loadLibrary("first");
}
}
first.c——libfirst.so的唯一翻译单元
#include <jni.h>
#include "Test.h"
#include <dlfcn.h>
#define LIBNAME "libsecond.so"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Test
* Method: test
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_Test_test(JNIEnv *env , jclass cls)
{
void* h;
void (*sym)(void);
h = dlopen(LIBNAME, RTLD_LAZY|RTLD_GLOBAL);
if (h) {
printf("dlopen " LIBNAME " worked\n");
sym = (void (*)(void))dlsym(h,"second");
sym();
} else {
printf("dlopen " LIBNAME " failed\n");
}
}
#ifdef __cplusplus
}
#endif
#include <stdio.h>
void
second(void)
{
printf("hello from second\n");
}
Makefile
CFLAGS=-fPIC
all : libfirst.so libsecond.so
libsecond.so : second.o
$(CC) -shared -Wl,-soname,libsecond.so.0 -o $@ $^ -lc
libfirst.so : first.o
$(CC) -shared -Wl,-soname,libfirst.so.0 -o $@ $^ -ldl -lc
clean:
rm -f *.o *.so
Test.h
可以通过javah Test
生成。请注意,libfirst.so
和libsecond.so
没有链接在一起。所有常用规则都适用于从Java加载的库中加载的dopen()
。特别是,您可以检查您的等。请参见是第二个。那么
是另一个JNI库还是仅由第一个使用的普通C库。那么
?如果它是一个JNI库,我想你可能需要用System.loadLibrary()
从Java加载它,而不是用dlopen()
从C加载它,虽然我不确定。second.so普通的C库只被first.so使用。在构建first.so
时,在其中链接libsecond.so
。谢谢你的快速响应。libsecond.so是由dlopen加载的。似乎只要按照正确的顺序加载库就足够了,如响应顶部所示(System.loadLibrary(“second”);System.loadLibrary(“first”);
)