Android系统Java层访问Native层函数

Android系统中Java层函数需要访问Native层函数的话,需要通过Jni,下面通过一个示例来演示windows环境下,在java中调用C库函数。

1、编写java代码。在java层写好类和函数,例如HelloJNI.java:

class HelloJNI {
    // 本地方法声明
    native void printHello();

    native void printString(String str);

    // 加载库
    static {
        System.loadLibrary("hellojni");
    }

    public static void main(String args[]) {
        HelloJNI myJNI = new HelloJNI();
        // 调用本地方法(实际调用的是使用C语言编写的JNI本地函数)
        myJNI.printHello();
        myJNI.printString("Hello World from printString fun");
    }
}

2、 编译java代码,在cmd命令行中使用javac命令编译上面的HelloJNI.java文件,生成HelloJNI.class文件: javac -encoding uft-8 HelloJNI.java
在当前目录下就有了.java文件和.class文件了。
3、生成C语言的头文件:我们这里使用的是javah命令来生成所需要的C语言的头文件HelloJNI.h。在cmd控制台中输入javah HelloJNI命令。生成的头文件HelloJNI.h如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */

#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloJNI
 * Method:    printHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloJNI_printHello
  (JNIEnv *, jobject);

/*
 * Class:     HelloJNI
 * Method:    printString
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_HelloJNI_printString
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

这里面有在java文件中声明的两个函数的原型。不要随意修改,在后面使用。
ps:这里主要是注册java在JIN层的函数,一般有静态和动态两种注册方法,这里采用的就是静态注册方法。
4、编写C/C++代码:
在hellojni.c文件中实现在头文件HelloJNI.h中声明的函数,注意补齐形参,并包含头文件:

#include "HelloJNI.h"
#include <stdio.h>
/*
* Class:     HelloJNI
* Method:    printHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printHello
    (JNIEnv *env, jobject obj){
        printf("Hello World!\n");
        return;
}

/*
* Class:     HelloJNI
* Method:    printString
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_HelloJNI_printString
    (JNIEnv *env, jobject obj, jstring string){
        const char *str = (*env)->GetStringUTFChars(env,string,0);
        printf("%s!\n",str);
        return;
}

5、生成共享库.dll文件:
5.1、首先将jdk目录下的jni.h(C:\Program Files\Java\jdk1.8.0_102\include\jni.h)和jni_md.h(C:\Program Files\Java\jdk1.8.0_102\include\win32\jni_md.h)这两个文件拷贝到vs的include(D:\Microsoft Visual Studio 11.0\VC\include)目录下。
5.2、将3和4中的.c文件和.h文件拷贝到D:\Microsoft Visual Studio 11.0\VC目录中,供编译使用。
5.3、在开始菜单中打开Microsoft Visual Studio 2012->Visual Studio Tools->VS2012 x64 兼容工具命令提示(根据自己平台选择32位还是64位,这里是选择的64位的)。在命令行中输入如下命令:

cl -I"<C:\Program Files\Java\jdk1.8.0_102>\include" -I"<C:\Program Files\Java\jdk1.8.0_102>\include\win32" -LD hellojni.c -Fehellojni.dll

ps:各种参数的含义:

cl:visual c++编译命令;
-I<dir>:添加要检索头文件的目录路径,这里需要包含jni.h和jni_md.h这两个头文件。虽然在上述命令中已经包含着两个头文件的目录路径,但还是存在无法找到头文件的情况,所以特地在4.1中将这两个头文件手动添加到了……\VC\include目录下。
-LD:创建dll文件;
-Fe<文件名>:指定编译结果文件名称;

6、运行java程序:将5中生成的hellojni.dll文件拷贝到java文件目录下,然后在cmd命令行中输入java HelloJNI运行java程序。根据书写的程序内容,应该在控制台中返回:

Hello World!
Hello World from printString fun!

至此就完成了在java中调用C库函数!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值