最近我正在学习JNI来执行C代码。当然,我做了网上的基本示例。现在我试图加载一个C库,使动态库加载(dlopen)。但我正在与错误斗争。我发布了我的Java代码,C ++代码和错误。
我的Java类
/**
*
* @author glassfish
*/
public class MediationJniWeb {
public String library ;
static {
System.loadLibrary("-core-web");
}
/**
*
* @param library name of mediation core library [32]
* @param method name of method to be executed [128]
* @param parameters parameters of method [10240]
* [partype1,value1,...,valuen]...[partypen,value1,..,valuen]
* @return
*/
private native String execute();
public static void main(String args[]) {
//new MediationJniWeb().callToFunction(null, null, null) ;
MediationJniWeb jniWeb = new MediationJniWeb();
jniWeb.library = "libtest.so" ;
System.out.println(jniWeb.execute());
}
}
我使用
生成.class文件javac MediationJniWeb
我用
生成.h文件javah -jni MediationJniWeb
我的MediationJniWeb.h文件是
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MediationJniWeb */
#ifndef _Included_MediationJniWeb
#define _Included_MediationJniWeb
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MediationJniWeb
* Method: execute
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_MediationJniWeb_execute
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
和我的MediationJniWEb.cpp文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <dlfcn.h>
#include <iostream>
#include "MediationJniWeb.h"
using namespace std ;
typedef void (*test)(string);
/*
* Class: MediationJniWeb
* Method: execute
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_MediationJniWeb_execute
(JNIEnv * env, jobject obj){
const char * str_library ;
jfieldID fid_library ;
jstring jstr_library ;
jboolean isCopy ;
jclass cls = env->GetObjectClass( obj) ;
fid_library = env->GetFieldID( cls,"library", "Ljava/lang/String;");
jstr_library = ( jstring )env->GetObjectField( obj,fid_library);
str_library = env->GetStringUTFChars( jstr_library, &isCopy) ;
void* handle = dlopen(str_library, RTLD_NOW); // open libtest.so
if ( 0 == handle ) {
cout << "failed to load 'libtest.so'. " << dlerror () <<endl;
exit(1);
}
test t = (test)dlsym(handle, "_Z8testfuncSs"); // run default method
if ( 0 == t ) {
cout << "failed to load 'testfunc()'." << endl;
exit(1);
}
t("Hello, World!");
dlclose(handle);
/*
*/
return env->NewStringUTF( str_library); // I just return library name just for fun
}
}
我用
编译g ++ -shared -fpic -I // include / -I // include / linux / MediationJniWeb.cpp -o lib-core-web.so MediationJniWeb.cpp -ldl
这会生成lib-core-web.so文件。然后我将其复制到$ HOME / lib并配置
LD_LIBRARY_PATH = $ HOME / lib中
现在我创建我的库libtest.so,它将由lib-core-web.so执行
我为共享libray mylib.cpp创建文件
#include <iostream>
#include <string>
using namespace std;
void testfunc(string s)
{
cout << s << endl;
}
我编译它将作为共享库使用
g ++ -shared -fpic -o libtest.so mylib.cpp
此命令生成libtest.so文件..而且,我将其复制到$ HOME / lib
我只是从JNI调用C ++库来加载动态库。 当我执行MediationJniWeb java类时,我遇到了这个错误
无法加载。 libtest.so:无法打开共享对象文件:没有这样的 文件或目录
我与libtest.so有什么关系?我该把它放在哪里?
我想到只使用正确的路径配置LD_LIBRARY_PATH变量,JVM应该知道在哪里可以找到要加载的所有需要的库。
请帮助您的意见,让我知道我的错误在哪里。
提前致谢!
答案 0 :(得分:1)
我做过的一件简单的事情
而不是
jniWeb.library =“libtest.so”
要加载的库参数我声明了
jniWeb.library =“/ home / myuser / lib / libtest.so”
它有效!