java 调用so文件

Python012

java 调用so文件,第1张

用JNI实现

实例:

创建HelloWorld.java

class HelloWorld

{

private native void print()

public staticvoid main(String[] args)

{

new HelloWorld().print()

}

static

{

System.loadLibrary("HelloWorld")

}

}

注意print方法的声明,关键字native表明该方法是一个原生代码实现的。另外注意static代码段的System.loadLibrary调用,这段代码表示在程序加载的时候,自动加载libHelloWorld.so库。

编译HelloWorld.java

在命令行中运行如下命令:

javac HelloWorld.java

在当前文件夹编译生成HelloWorld.class。

生成HelloWorld.h

在命令行中运行如下命令:

javah -jni HelloWorld

在当前文件夹中会生成HelloWorld.h。打开HelloWorld.h将会发现如下代码:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class HelloWorld */

#ifndef _Included_HelloWorld

#define _Included_HelloWorld

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: HelloWorld

* Method:print

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_HelloWorld_print

(JNIEnv *, jobject)

#ifdef __cplusplus

}

#endif

#endif

该文件中包含了一个函数Java_HelloWorld_print的声明。这里面包含两个参数,非常重要,后面讲实现的时候会讲到。

实现HelloWorld.c

创建HelloWorld.c文件输入如下的代码:

#include <jni.h>

#include <stdio.h>

#include "HelloWorld.h"

JNIEXPORT void JNICALL

Java_HelloWorld_print(JNIEnv *env, jobject obj)

{

printf("Hello World!\n")

}

注意必须要包含jni.h头文件,该文件中定义了JNI用到的各种类型,宏定义等。

另外需要注意Java_HelloWorld_print的两个参数,本例比较简单,不需要用到这两个参数。但是这两个参数在JNI中非常重要。

env代表java虚拟机环境,Java传过来的参数和c有很大的不同,需要调用JVM提供的接口来转换成C类型的,就是通过调用env方法来完成转换的。

obj代表调用的对象,相当于c++的this。当c函数需要改变调用对象成员变量时,可以通过操作这个对象来完成。

编译生成libHelloWorld.so

在Linux下执行如下命令来完成编译工作:

cc -I/usr/lib/jvm/java-6-sun/include/linux/

-I/usr/lib/jvm/java-6-sun/include/

-fPIC -shared -o libHelloWorld.so HelloWorld.c

在当前目录生成libHelloWorld.so。注意一定需要包含Java的include目录(请根据自己系统环境设定),因为Helloworld.c中包含了jni.h。

另外一个值得注意的是在HelloWorld.java中我们LoadLibrary方法加载的是

“HelloWorld”,可我们生成的Library却是libHelloWorld。这是Linux的链接规定的,一个库的必须要是:lib+库

名+.so。链接的时候只需要提供库名就可以了。

运行Java程序HelloWorld

大功告成最后一步,验证前面的成果的时刻到了:

java HelloWorld

如果你这步发生问题,如果这步你收到java.lang.UnsatisfiedLinkError异常,可以通过如下方式指明共享库的路径:

java -Djava.library.path='.' HelloWorld

当然还有其他的方式可以指明路径请参考《在Linux平台下使用JNI》。

我们可以看到久违的“Hello world!”输出了。

在java程序设置环境变量:

String path = System.getProperty("java.library.path")

path = path+"你要添加的路径"

System.setProperty("java.library.path",path)

问题补充:当在一个运行进程中设置环境变量,只可以运用于当前进程,所以。。谢谢。从网上搜到可以使用jna,调用 本地方法的方式 实现。因为c/c++实现了setenv()方法

小卓SUN 写道

自己写个batch文件,直接runtime调用啊

runtime.exec(xxx.bat, "路径")