使用JNI加载动态C共享库,JNI还加载另一个共享库

使用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库

在JavaEclipse(Linux)上使用JNI,我首先加载一个名为的动态共享库。 到目前为止一切进展顺利。 问题在于,first.so还加载了一个名为second.so的动态库

运行该程序时,我收到许多关于秒内符号的“未定义符号”错误。因此

似乎使用JNI加载的库无法在运行时加载其他C库,因为我们处于Java环境中。我的假设正确吗? 我需要特殊的编译标志来编译第一个.so库,还是需要特殊的参数来告诉eclipse它将在运行时加载.so

提前谢谢

似乎使用JNI加载的库无法在运行时加载其他C库,因为我们处于Java环境中。我的假设正确吗

没有

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”);