JNI Hello World
阅读原文时间:2023年07月11日阅读:2

1、什么是JNI:

JNI(Java Native Interface):java本地开发接口

              JNI是一个协议,这个协议用来沟通java代码和外部的本地代码(c/c++)

              外部的c/c++代码也可以调用java代码

       2、为什么使用JNI

              效率上 C/C++是本地语言,比java更高效

              代码移植,如果之前用C语言开发过模块,可以复用已经存在的c代码

              java反编译比C语言容易,一般加密算法都是用C语言编写,不容易被反编译

       3、Java基本数据类型与C语言基本数据类型的对应

              

      3、引用类型对应

              

       4、堆内存和栈内存的概念

              栈内存:系统自动分配和释放,

                      保存全局、静态、局部变量,

                      在站上分配内存叫静态分配,

                      大小一般是固定的

              堆内存:程序员手动分配(malloc/new)和释放(free/java不用手动释放,由GC回收),

                      在堆上分配内存叫动态分配,

                      一般硬件内存有多大堆内存就有多大

二、交叉编译

       1、交叉编译的概念

          交叉编译即在一个平台,编译出另一个平台能够执行的二进制代码

          主流平台有: Windows、 Mac os、 Linux

          主流处理器: x86、 arm、 mips

       2、交叉编译的原理

          即在一个平台上,模拟其他平台的特性

          编译的流程: 源代码-->编译-->链接-->可执行程序

       3、交叉编译的工具链

          多个工具的集合,一个工具使用完后接着调用下一个工具

在C中实现这个方法,在方法内部输出“Hello World",然后再回到Java中进行调用。分为以下步骤:

建立一个类:JNIDemo

public class JNIDemo {
static { /* 1. load */
System.loadLibrary("native"); /* libnative.so */
}
public native static void hello();
public native static int hello(String str, int []a);
public static void main(String[] args) {

    System.out.println("JNIDemo");

    /\* 1. load \*/  
    System.loadLibrary("native"); /\* libnative.so \*/

    /\* 2. map hello java<-->c c\_hello \*/

    /\* 3. call \*/  
    hello();  
 } 

}

编译java

$ javac JNIDemo.java

gen jiu java wenjian cahn sheng tou wenjian xie C wenjian

$ javah -jni JNIDemo

Output JNIDemo.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class JNIDemo */

#ifndef _Included_JNIDemo
#define _Included_JNIDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JNIDemo
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JNIDemo_hello__
(JNIEnv *, jclass);

/*
* Class: JNIDemo
* Method: hello
* Signature: (Ljava/lang/String;[I)I
*/
JNIEXPORT jint JNICALL Java_JNIDemo_hello__Ljava_lang_String_2_3I
(JNIEnv *, jclass, jstring, jintArray);

#ifdef __cplusplus
}
#endif
#endif

new native.c

#include /* /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ */
#include

#if 0
typedef struct {
char *name; /* Java里调用的函数名 */
char *signature; /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */
void *fnPtr; /* C语言实现的本地函数 */
} JNINativeMethod;
#endif

void c_hello(JNIEnv *env, jobject cls)
{
printf("Hello, world!\n");
}

static const JNINativeMethod methods[] = {
{"hello", "()V", (void *)c_hello},
};

/* System.loadLibrary */
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
jclass cls;

if ((\*jvm)->GetEnv(jvm, (void \*\*)&env, JNI\_VERSION\_1\_4)) {  
    return JNI\_ERR; /\* JNI version not supported \*/  
}  
cls = (\*env)->FindClass(env, "JNIDemo");  
if (cls == NULL) {  
    return JNI\_ERR;  
}

/\* 2. map hello java<-->c c\_hello \*/  
if((\*env)->RegisterNatives(env, cls, methods, 1) < 0)  
    return JNI\_ERR;

return JNI\_VERSION\_1\_4;  

}

指定头文件路径 -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ 编译产生库

$ gcc -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ -fPIC -shared -o libnative.so native.c

运行

$ java JNIDemo

结果

JNIDemo
Hello, world!

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章