生成so库供Java调用

来源:互联网 发布:淘宝装修教程完整版 编辑:程序博客网 时间:2024/04/28 23:38

需求

在上次完成的gpio控制中,把c文件编译成一个so库,供java程序调用.

准备工作

首先在网上查找了大量的资料,然后一步一步的按照网上的教程在linux平台下面走了一边,包括.java文件编译成.class文件,然后生成.h文件,然后用c语言实现该方法即可.大概流程就是这样,觉得很简单.下午往android代码里面添加的时候发现很多问题.下面把详细步骤记录下来.

步骤

平台:展讯的7715,安卓7.0
java代码很简单,直接调用一个方法即可.用的还是HelloWorld示例.

System.loadLibrary(“HelloWorld”); class HelloWorld {    static {        System.loadLibrary("HelloWorld");       }    private native void greeting();    public static void main(String[] args) {        new HelloWorld().greeting();    } }

编译生成.class文件,然后通过javah HelloWorld生成.h文件,然后编写.c文件包含.h文件并实现.h文件里面的方法.

#include "HelloWorld.h"#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <linux/ioctl.h>#define DEV_IOC_MAGIC '0xee' //定义幻数#define DEV_IOCPRINT  _IO(DEV_IOC_MAGIC, 1)#define DEV_IO_HIGH   _IO(DEV_IOC_MAGIC, 2)#define DEV_IO_LOW    _IO(DEV_IOC_MAGIC, 3)#define DEV_IOC_MAXNR 3JNIEXPORT void JNICALL Java_HelloWorld_greeting  (JNIEnv *env, jobject obj) {    printf("Hello World!");    int cmd;    int fd;    int choice = 0;    fd = open("/dev/dsx", O_RDWR);    if(fd < 0)        printf("ni  haishi  dabukai  ya !\n");    /*命令1:打印串口信息*/    while(1)    {        int i=0;        printf("Please input choice: \n 1: DEV_IOCPRINT; \n 2: DEV_IO_HIGH\n 3: DEV_IO_LOW \n 4: EXIT \n");        scanf("%d", &choice);        if(choice == 4)        {            printf("gpio test exit\n");            break;        }        switch(choice)        {            case 1:            {                printf("<--- Call DEV_IOCPRINT --->\n");                cmd = DEV_IOCPRINT;                if (ioctl(fd, cmd) < 0)                {                    printf("Call cmd MEMDEV_IOCPRINT fail\n");                }                break;            }            case 2:            {                printf("<--- Call DEV_IO_HIGH --->\n");                cmd = DEV_IO_HIGH;                if (ioctl(fd, cmd) < 0)                {                    printf("Call cmd DEV_IO_HIGH fail\n");                }                break;            }            case 3:            {                printf("<--- Call DEV_IO_LOW --->\n");                cmd = DEV_IO_LOW;                if (ioctl(fd, cmd) < 0)                {                    printf("Call cmd DEV_IO_LOW fail\n");                }                break;            }            default:                break;        }        printf("\n\n===================================\n");    }}

直接把原来的代码里面的main函数放到了Java_HelloWorld_greeting里面.
本以为这样就可以了,但是编译生成的so库放到开发板里面怎么都不行,经过师傅的讲解以后(下面的步骤很关键哦),在external下面新建一个文件夹,然后把.c文件和.h文件放进来,最重要的是要写一个Android.mk文件.然后编译安卓源代码就可以了.

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_ARM_MODE :=armLOCAL_MODULE := **libHelloWorld**//一定要加上libLOCAL_SRC_FILES := HelloWorld.cLOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)include $(BUILD_SHARED_LIBRARY)

然后编译该目录,会在system/bin下面生成libHelloWorld.so.这个才是最终生成的so文件,把它push进开发板的system/lib目录下面,然后在开发板中运行刚才写的java代码生成的.class就可以了.

感悟

这个任务其实挺简单的,多查资料,实在搞不明白的问问师傅,很快就可以解决.

原创粉丝点击