a example of JNI static way:
first step: write a middle java file:
mkdir jni
cd jni/
vim TestJni.java
import java.util.*;
public class TestJni
{
public native void xprint(String content);
static
{
System.loadLibrary("TestJni");
}
}
javac TestJni.java and make a class
then
javah -jni TestJni to make a .h file:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestJni */
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJni
* Method: xprint
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_TestJni_xprint
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
step two write jni file.c:
TestJni.c:
#include<jni.h>
#include<stdio.h>
#include "TestJni.h"
JNIEXPORT void JNICALL Java_TestJni_xprint(JNIEnv *env,jobject obj,jstring content)
{
const jbyte *str=(const jbyte*)(*env)->GetStringUTFChars(env,content,JNI_FALSE);
printf("hello--wo%s \n",str);
(*env)->ReleaseStringUTFChars(env,content,(const char*)str);
return;
}
three build .so lib
cc -I/usr/jdk-8/include/ -I/usr/jdk-8/include/linux/ -I .../jni/ -fPIC -shared -o libTestJni.so TestJni.c
four write a test:hellow.java
import java.util.*;
public class hellow
{
public static void main(String argc[])
{
new hellow();
}
public hellow()
{
new TestJni().xprint("hi my name is keee");
}
}
question:
如果你这步发生问题,如果这步你收到java.lang.UnsatisfiedLinkError异常,可以通过如下方式指明共享库的路径:
java -Djava.library.path=’.’ HelloWorld
或者输入命令:
export LD_LIBRARY_PATH=“HelloWorld路径”:$LD_LIBRARY_PATH 设置环境变量
然后再 java HelloWorld 一样OK
reference
http://www.cnblogs.com/bastard/archive/2012/05/17/2506877.html
http://www.cnblogs.com/wzben/p/5733571.html
a example of JNI dynamic way:
step 1:
write a TestJni.java
public class SimpleJni{
static {
System.out.println("[java] static code block,start load shared library...");
System.loadLibrary("SimpleJni");
System.out.println("[java]load library end...");
}
static native int add(int a,int b);
public static void main(String args[])
{
System.out.println("[java] in main...");
System.out.println("[java] 3+4="+SimpleJni.add(3,4));
System.out.println("end...");
}
}
step 2:
write a Jni file:
#include <jni.h>
#include<stdio.h>
const char *classPathName=”com/bt/jni/SimpleJni”;
jint myadd(JNIEnv *env,jobject thiz,jint a,jint b)
{
return a+b;
}
static JNINativeMethod methods[]={
{"add","(II)I",(void*)myadd},};
int registerNatives(JNIEnv *env)
{
jclass clazz;
clazz=(*env)->FindClass(env,classPathName);
if(NULL==clazz){
printf("[C] FindClass fail\n");
goto failed;
}
if (0>(*env)->RegisterNatives(env,clazz,methods,sizeof(methods)/sizeof(methods[0]))){
printf("RegisterNatives fail.\n");
goto failed;
}
return JNI_TRUE;
failed:
return JNI_FALSE;
}
jint JNI_OnLoad(JavaVM *vm,void *reserved)
{
JNIEnv *env=NULL;
jint result=-1;
void **env_p=NULL;
printf("start register native func\n");
env_p=(void**)&env;
if(JNI_OK!=(*vm)->GetEnv(vm,env_p,0x00010006)){
printf("get env failed..\n");
goto err;
}
if(JNI_TRUE!=registerNatives(env)){
printf("register fail...exit....\n");
goto err;
}
result=0x00010006;
err:
return result;
}
step use:
1.首先编写SimpleJni.java和simpel_jni.c
2.编译java和c文件
$ java -d . SimpleJni.java
$gcc -fPIC -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/ -o libsimpleJni.so simple_jni.c
3.执行
$java -Djava.library.path=. com.bt.jni.SimpleJni
other example:
java file:
import java.util.*;
public class TestJni
{
public native void xprint(String content);
static
{
System.loadLibrary(“TestJni”);
}
public native static String native_hello();
}
JNI file:
#include<jni.h>
#include<stdio.h>
//#include "TestJni.h"
#include<iostream>
using namespace std;
void xprint(JNIEnv *env,jobject obj,jstring content)
{
// const jbyte *str=(const jbyte*)(env->GetStringUTFChars(env,content,JNI_FALSE));
//printf("hello--wo%s \n",str);
// env->ReleaseStringUTFChars(env,content,(const char*)str);
cout<<"here:"<<content<<endl;
return;
}
static jstring native_hello(JNIEnv *env,jobject object)
{
return (env)->NewStringUTF("keshixi");
}
static JNINativeMethod method_table[]={
{ "xprint","(Ljava/lang/String;)V",(void*)xprint},
{"native_hello","()Ljava/lang/String;",(void*)native_hello}
// {,,(void*)xprint},{,,(void*)native_hello}
};
jint JNI_OnLoad(JavaVM *jvm,void *reserved){
JNIEnv *env;
if(jvm->GetEnv((void**)&env,JNI_VERSION_1_6)!=JNI_OK){
return -1;
}
jclass clz=env->FindClass("TestJni");
if(clz==NULL)
{
return JNI_FALSE;
}
if(env->RegisterNatives(clz,method_table,sizeof(method_table)/sizeof(method_table[0]))==JNI_OK){
return JNI_VERSION_1_6;
}
}
####reference:
jni有两种使用方式,一种是静态注册的,依赖于头文件的。另一种是动态注册的不依赖头文件,静态的看里面文件夹的实例和博客就行
动态方式也可以参见dy文件夹下的网页教程,以及对应的两个例子
另外可以作为ndk在android中使用及在android stdio也可以直接生成so
一些链接:android_jni_ndk:http://www.cnblogs.com/wzben/p/5733571.html
动态注册无运行实例:http://www.linuxidc.com/Linux/2017-02/140130.htm
静态注册:http://www.cnblogs.com/bastard/archive/2012/05/17/2506877.html
动态注册:有实例http://www.linuxidc.com/Linux/2017-02/140129.htm