設定が正しいように見えますが、JNIからC関数を呼び出すときにUnsatisfiedLinkErrorが表示されます。ここで私がやったものだ:UnsatisfiedLinkErrorでJNI呼び出しが失敗する
Javaクラスがあります:
package com.mycompany.myproduct;
public class Foo {
static {
System.loadLibrary("external");
}
public void native do_foo();
}
私は、LD_LIBRARY_PATH
にlibexternal.so
を置いたクラスをコンパイルし、その上にjavah
を実行してきました。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_mycompany_myproduct_Foo */
#ifndef _Included_com_mycompany_myproduct_Foo
#define _Included_com_mycompany_myproduct_Foo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_com_mycompany_myproduct_Foo
* Method: do_foo
* Signature:()V
*/
JNIEXPORT void JNICALL Java_com_mycompany_myproduct_Foo_do_1foo(JNIEnv *, jobject);
は(extern "C"
がそこに必要とされているかどうかわからない)ctinative.c
でCの委任を実装:
ctinative.o
を得た
#include "com_mycompany_myproduct_Foo.h"
#include "External.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_com_mycompany_myproduct_Foo
* Method: do_foo
* Signature:()V
*/
JNIEXPORT void JNICALL Java_com_mycompany_myproduct_Foo_do_1foo(JNIEnv *, jobject) {
do_foo(); // this is a function that defined in External.h
}
#ifdef __cplusplus
}
#endif
:
gcc -x c -g -m64 -DUNIX=1 -DUSE_SBUF=1 -DMAIN_VERSION=0 -DC_VER=7 -I$(EXTERNAL_SDK_ROOT)/include -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -o ctinative.o -c ctinative.c
ここで出力だcom_mycompany_myproduct_Foo.h
ファイルを結果nm ctinative.o
(U
が正常ですか?):
0000000000000000 T Java_com_mycompany_myproduct_Foo_do_1foo
U do_foo
これは、ctinative.o
~LD_LIBRARY_PATH
となります。 Foo.do_foo()
を呼び出すときに今、私はないUnsatisfiedLinkErrorを取得しています:私はLD_LIBRARY_PATH
からctinative.o
を削除
java.lang.UnsatisfiedLinkError: com.mycompany.myproduct.Foo.do_foo()V
at com.mycompany.myproduct.Foo.do_foo(Native Method)
場合はエラーは変更されません。私はLD_LIBRARY_PATH
からlibexternal.so
を削除する場合は、もちろん私は取得しています:
java.lang.UnsatisfiedLinkError: no external in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at com.mycompany.myproduct.Foo.<clinit>
私が間違ってやっている上の任意のアイデアを?
1つの試み:明示的にlibパスを指定してチェックしてみましょう。-Djava.library.path =/YOUR/PATH/TOLIB/DIR/'または' loadLibrary() 'でフルパスを指定するか、結果を教えてください –
libexternal.soにはどのようなコードがありますか? – msandiford
@spong:私のC実装ファイルにincludeしているExternal.hは、libexternal.soのヘッダファイルです。とりわけ、私が呼び出そうとしているC関数do_foo()を宣言しています。 –