2013-02-25 1 views
0

Недавно я изучаю JNI для выполнения кода C. Конечно, я сделал основные примеры, которые были в Интернете. Теперь я пытаюсь загрузить библиотеку C, которая выполняет динамическую загрузку библиотеки (dlopen). Но я сражаюсь с ошибкой. Я отправляю свой код Java, код на C++ и ошибку.Загрузка динамических библиотек с использованием JNI и C++ с помощью linux

Мой 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 МедиацияJniWeb

мой 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 
    } 

    } 

Я компилировать с

г ++ -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/Библиотека

Теперь я создаю моя библиотека libtest.so, которая будет выполнена Lib-ядро-сети .so

создать файл для общей libray mylib.cpp

#include <iostream> 
#include <string> 

using namespace std; 

void testfunc(string s) 
{ 
    cout << s << endl; 
} 

я компилирую это, что будет работать в общей библиотеке с

г ++ -shared -fpic -o libtest.so mylib.cpp

Эта команда создает файл libtest.so .. а также, скопировать его в $ HOME/Lib

Это все Я звоню из JNI в библиотеку C++ для загрузки динамической библиотеки. при выполнении MediationJniWeb java class У меня такая ошибка

не удалось загрузить. libtest.so: не может открыть общий объектный файл: Нет такого файл или каталог

Что я должен делать с libtest.so ?? где я должен это выразить?

Я помню, что при настройке только переменной LD_LIBRARY_PATH с правильным путем JVM должна знать, где найти все необходимые библиотеки для загрузки.

Помогите с вашими комментариями и сообщите мне, где мои ошибки.

Заранее благодарен!

+1

Возможно, вы захотите рассмотреть возможность использования JNA ... это устранит необходимость в большей части кода, который вы написали. –

+0

JNA звучит intersting, но цель этого в том, что я загружу свой собственный набор библиотек c (у нас есть большое приложение, которое использует многие .so-файлы) и, возможно, вызовет некоторые проблемы с выполнением. Кстати, я хотел бы узнать, есть ли у вас опыт использования собственного доступа из Интернета. Если это полезно или есть некоторые проблемы или проблемы на момент развертывания – smeerkahoven

ответ

1

Простая вещь, которую я сделал

вместо

jniWeb.library = "libtest.so"

библиотека параметр должен быть загружен я объявил

jniWeb.library = "/home/myuser/lib/libtest.so"

И это сработало!

Смежные вопросы