首先,我的示例具有以下目录结构:
Sample.c
lib/
mypackage/
--Sample.java
Sample.java
在mypackage
看起来像这样:
package mypackage;
public class Sample {
public static native int sampleMethod(int x);
public static void main(String[] args) {
System.loadLibrary("Sample");
System.out.println("sampleMethod result: " + sampleMethod(5));
}
}
我运行javac mypackage/Sample.java
编译java文件并javah mypackage.Sample
生成JNI
头文件。然后我使用以下命令编译库:
clang -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/darwin" -o lib/libSample.so -shared Sample.c
此时目录结构如下所示:
Sample.c
mypackage_Sample.h
lib/
--libSample.so
mypackage/
--Sample.java
--Sample.class
现在,当我尝试使用运行示例时java -Djava.library.path=./lib/ mypackage.Sample
,出现以下错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no Sample in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at mypackage.Sample.main(Sample.java:7)
我尝试指定到 的完整路径lib/
,但出现相同的错误。
我不确定标题和实现的代码是否重要,但无论如何我都会发布它们。
mypackage_Sample.h
:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mypackage_Sample */
#ifndef _Included_mypackage_Sample
#define _Included_mypackage_Sample
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mypackage_Sample
* Method: sampleMethod
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_mypackage_Sample_sampleMethod
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
Sample.c
:
#include "mypackage_Sample.h"
#include <stdio.h>
JNIEXPORT jint JNICALL Java_mypackage_Sample_sampleMethod
(JNIEnv * env, jclass obj, jint num) {
return num * num;
}
我在OS X Yosemite 10.10.5
使用clang 7.0.2
和运行它java 1.8.0_101
。
您的库文件 ( libSample.so
) 中的名称似乎有误。
如果您使用:
System.loadLibrary("Sample");
JVM 会将此名称映射到特定于平台的文件名以尝试加载。在 Linux 上是这样libSample.so
,在 Windows 上是这样Sample.dll
,但在 OS X 上则是另外一回事。
您可以通过查看以下输出来找出您的库文件应具有的名称:
System.mapLibraryName("Sample");
在目标平台上调用。
之后,您可以将其用作库文件的名称。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句