0

最近、Cコードを実行するためにJNIを学んでいます。もちろん、Web 上にある基本的な例を作成しました。今、動的ライブラリー・ロード (dlopen) を行う C ライブラリーをロードしようとしています。しかし、私はエラーと戦っています。私の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

次に、lib-core-web.so によって実行されるライブラリ libtest.so を作成します。

共有ライブラリ 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 は、ロードする必要のあるすべてのライブラリを見つける場所を認識している必要があります。

あなたのコメントを助けて、私の間違いがどこにあるか教えてください。

前もって感謝します !

4

1 に答える 1

1

私がした簡単なこと

それ以外の

jniWeb.library = "libtest.so"

ロードするライブラリパラメータを宣言しました

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

そしてそれはうまくいきました!

于 2013-02-25T21:47:36.710 に答える