现在的位置: 首页 > 操作系统 > 正文

JNI通过动态注册实现native函数

2020年02月10日 操作系统 ⁄ 共 2257字 ⁄ 字号 评论关闭

一、概述通过javah工具将java代码中的native声明的函数生成标准的C/C++函数头,每个函数的名字都很长(Java_包名_类名_函数名),这样C/C++函数的函数名就是定死的,不能修改,否则java找不到函数。这里还有种方式,通过注册的方式将C/C++的函数与java中的native函数进行一一对应的,函数名可以任意书写。

二、代码实现SimpleJni.java

package com.bt.jni; 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 + 5 = " + SimpleJni.add(3, 5)); System.out.println("[java] main() end..."); } }

simple_jni.c#include "jni.h" #include <stdio.h> const char *classPathName = "com/bt/jni/SimpleJni"; /** native 函数的实现 **/jint myadd(JNIEnv *env, jobject thiz, jint a, jint b) { return a + b; } static JNINativeMethod methods[] = { //{native函数名,函数签名, C中函数实现名} {"add", "(II)I", (void*)myadd}, }; int registerNatives(JNIEnv *env) { jclass clazz; //根据类的全路径,获得类的字节码信息 clazz = (*env)->FindClass(env, classPathName); if (NULL == clazz) { printf("[C] FindClass() failed...\n"); goto failed; } //将c函数与字节码中的native函数进行映射 if (0 > (*env)->RegisterNatives(env, clazz, methods, sizeof(methods)/sizeof(methods[0]))) { printf("[C] RegisterNatives() failed...\n"); goto failed; } return JNI_TRUE; failed: return JNI_FALSE; } /** java 在加载动态库的时候,自动调用此函数,注册native函数 **/jint JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env = NULL; jint result = -1; void **env_p = NULL; printf("[C] start register native func...\n"); env_p = (void**)&env; //首先从java虚拟机中获得env if (JNI_OK != (*vm)->GetEnv(vm, env_p, 0x00010004)) { printf("[C] GetEnv() failed...will exit\n"); goto err; } //通过env进行函数的注册 if (JNI_TRUE != registerNatives(env)) { printf("[C] register func failed...will exit\n"); goto err; } result = 0x00010004; printf("[C] register end...\n"); err: return result; }

操作步骤 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

结果: [java]static code block, start load shared library.... [C] start register native func... [C] register end... [java]load library end.... [java] in main()... [java] 3 + 5 = 8 [java] main() end...

根据结果可知,java首先执行静态代码块,其中在加载动态库的时候,自动调用JNI_OnLoad函数,建立native函数和c中的函数映射关系,最后进入main函数。

本文永久更新链接地址:http://www.xuebuyuan.com/Linux/2017-02/140129.htm

以上就上有关JNI通过动态注册实现native函数的全部内容,学步园全面介绍编程技术、操作系统、数据库、web前端技术等内容。

抱歉!评论已关闭.