文档章节

Android JNI 调用 C/C++

RoyceInWh
 RoyceInWh
发布于 2016/06/20 16:04
字数 622
阅读 5
收藏 0

Android JNI 调用 C/C++ 接口

Android 使用 NDK 原生支持调用 c/c++ 接口的代码,只需要在程序中按照 android jni 规范编程就可以直接使用。

C 语言版本

JNI 调用 c 语言相对简单,命名一个 jni 函数,系统会自动注册到 Java 虚拟机,然后 Java 代码里面可以直接调用:

Native 代码:

#include <jni.h>

int add(int x, int y) {
	return x + y;
}
jint
Java_com_example_android_simplejni_SimpleJNI_add( JNIEnv*  env,
                                      jobject  this,
                                      jint     x,
                                      jint     y )
{
    return add(x, y);

需要注意的是函数名必须是跟 Java 类对应的,比如例子中的包为: package com.example.android.simplejni;  类名为: public class SimpleJNI 

方法名为: add

然后 Java 类代码里面可以直接加载库,声明为自己的方法:

package com.example.android.simplejni;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class SimpleJNI extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        System.loadLibrary("simplejni");
        int sum = add(2, 3);
        tv.setText("2 + 3 = " + Integer.toString(sum));
        setContentView(tv);
    }
    public native int add(int  x, int  y);
}

C++ 版本

c++ 语言由于跟 Java 一样是面向对象的设计语言,具有更多的特性,只是传递函数就不需要 c++ 了。 那么使用 C++ 代码注册到 Java 虚拟机就相对麻烦一些。

需要手动注册方法: 直接给 代码 吧:development/samples/SimpleJNI/jni/native.cpp

#define LOG_TAG "simplejni native.cpp"
#include <utils/Log.h>

#include <stdio.h>

#include "jni.h"

static jint
add(JNIEnv *env, jobject thiz, jint a, jint b) {
int result = a + b;
    ALOGI("%d + %d = %d", a, b, result);
    return result;
}

static const char *classPathName = "com/example/android/simplejni/Native";

static JNINativeMethod methods[] = {
  {"add", "(II)I", (void*)add },
};

/*
 * Register several native methods for one class.
 */
static int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;

    clazz = env->FindClass(className);
    if (clazz == NULL) {
        ALOGE("Native registration unable to find class '%s'", className);
        return JNI_FALSE;
    }
    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
        ALOGE("RegisterNatives failed for '%s'", className);
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

/*
 * Register native methods for all classes we know about.
 *
 * returns JNI_TRUE on success.
 */
static int registerNatives(JNIEnv* env)
{
  if (!registerNativeMethods(env, classPathName,
                 methods, sizeof(methods) / sizeof(methods[0]))) {
    return JNI_FALSE;
  }

  return JNI_TRUE;
}


// ----------------------------------------------------------------------------

/*
 * This is called by the VM when the shared library is first loaded.
 */
 
typedef union {
    JNIEnv* env;
    void* venv;
} UnionJNIEnvToVoid;

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    UnionJNIEnvToVoid uenv;
    uenv.venv = NULL;
    jint result = -1;
    JNIEnv* env = NULL;
    
    ALOGI("JNI_OnLoad");

    if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("ERROR: GetEnv failed");
        goto bail;
    }
    env = uenv.env;

    if (registerNatives(env) != JNI_TRUE) {
        ALOGE("ERROR: registerNatives failed");
        goto bail;
    }
    
    result = JNI_VERSION_1_4;
    
bail:
    return result;
}

Java :SimpleJNI/src/com/example/android/simplejni/SimpleJNI.java

package com.example.android.simplejni;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class SimpleJNI extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        int sum = Native.add(2, 3);
        tv.setText("2 + 3 = " + Integer.toString(sum));
        setContentView(tv);
    }
}

class Native {
    static {
    	// The runtime will add "lib" on the front and ".o" on the end of
    	// the name supplied to loadLibrary.
        System.loadLibrary("simplejni");
    }

    static native int add(int a, int b);
}



本文转载自:http://blog.csdn.net/jingxia2008/article/details/43017059

RoyceInWh

RoyceInWh

粉丝 5
博文 240
码字总数 1282
作品 0
武汉
程序员
私信 提问
JNI和NDK的区别

NDK(Native Development Kit)“原生”也就是二进制 android常用的开发方式是java封装的库,而这些库的底层实现是由C/C++实现,如媒体,图形库等 java调用这样实现就需要用JNI(Java Native...

长平狐
2013/01/06
106
0
android JNI使用方法

经过几天的努力终于搞定了android JNI部分,下面将我的这个小程序和大家分享一下。android JNI是连接android Java部分和C/C++部分的纽带,完整使用JNI需要Java代码和C/C++代码。其中C/C++代码...

linuxhunter
2011/12/26
3.9K
2
JNI和NDK的区别

NDK(Native Development Kit)“原生”也就是二进制 android常用的开发方式是java封装的库,而这些库的底层实现是由C/C++实现,如媒体,图形库等 java调用这样实现就需要用JNI(Java Native...

鉴客
2012/03/09
215
0
JNI和NDK的区别

NDK(Native Development Kit)“原生”也就是二进制 android常用的开发方式是java封装的库,而这些库的底层实现是由C/C++实现,如媒体,图形库等 java调用这样实现就需要用JNI(Java Native...

晨曦之光
2012/03/01
1K
0
Android NDK开发简介

最近由于项目的需要,使用到了Android的NDK技术,对项目核心算法跨平台的移植。简答而言,就是使用C对原来的算法进行了改进,并集成到原来的app项目里。 从前的项目一直没有使用NDK进行开发的...

zhiweiofli
2013/03/07
2.2K
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
10
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0
PHP+Ajax微信手机端九宫格抽奖实例

PHP+Ajax结合lottery.js制作的一款微信手机端九宫格抽奖实例,抽奖完成后有收货地址添加表单出现。支持可以设置中奖概率等。 奖品列表 <div class="lottery_list clearfix" id="lottery"> ......

ymkjs1990
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部