1. JNIEnv对象

对于本地函数

JNIEXPORT void JNICALL Java_video1_TestNative_sayHello(JNIEnv * env, jobject obj)

{

cout<

}

JNIEnv类型代表Java环境。通过这个JNIEnv*指针,就可以对Java端的代码进行操作。如,创建Java类得对象,调用Java对象的方法,获取Java对象的属性等。

JNIEnv的指针会被JNI传送到本地方法的实现函数中来对Java端的代码进行操作

JNIEnv类中的函数:

NewObject/NewString/NewArray  :new新对象

Get/SetField:获取属性

Get/SetStaticField :获取静态属性

CallMethod/CallStaticMethod:调用方法

2. Java数据类型与C/C++数据类型的对应关系

可以参考jni.h文件:http://home.pacifier.com/~mmead/jni/cs510ajp/jni.h

Java类型      别名             C++本地类型          字节(bit)

boolean      jboolean            unsignedchar      8, unsigned

bytejbyte               signedchar       8

charjchar               unsignedshort     16, unsigned

shortjshortshort               16

intjintlong               32

longjlong               __int6464

floatjfloatfloat32

doublejdoubledouble              64

void         voidn/a

Object        _jobject            *jobject

3. 获取jclass

为了能够在C/C++使用Java类,jni.h头文件中专门定义了jclass类型来表示Java中的Class类

jclass的取得:

JNIEnv类中有如下几个简单的函数可以取得jclass

jclass FindClass(const char* clsName)  根据类名来查找一个类,完整类名。

jclass GetObjectClass(jobject obj)   根据一个对象,获取该对象的类

jclass GetSuperClass(jclass obj)     获取一个类的父类

FindClass 会在classpath系统环境变量下寻找类,需要传入完整的类名,注意包与包之间是用"/"而不是"."来分割

如:jclass cls_string= env->FindClass("java/lang/String");

获取jclass又什么用,比如你要调用类的静态方法,静态属性就需要通过这个方法来获取一个类。

4. 本地代码访问Java类中的属性与方法

有了类和对象之后,如何才能访问java中的对象的属性和方法呢,这就需要用到以下这些方法了。

JNI在jni.h头文件中定义了jfieldID,jmethodID类表示Java端的属性和方法

如何获取属性: 在访问或设置Java属性的时候,首先就要现在本地代码中取得代表Java属性的jfieldID,然后才能在本地代码中进行Java属性操作。

如何调用java的方法:调用Java端的方法时,需要取得代表方法的jmethodID才能进行Java方法调用

JNIEnv获取相应的fieldID和jmethodID的方法:

GetFieldID/GetMethodID

GetStaticFieldID/GetStaticMethodID

GetMethodID也可以取得构造函数的jmethodID。创建Java对象时调用指定的构造函数。

如:env->GetMethodID(data_Clazz,"method_name","()V")

(*jniEnv)->GetMethodID(jniEnv, Clazz,"", "()V");

这个比较特殊,这个是默认构造函数的方法,一般用这个来初始化对象,但是再实际过程中,为了快速生成一个实例,一般通过工厂方法类创建jobject

jni.h 对GetMethodID的定义:

jmethodID (JNICALL *GetMethodID)

(JNIEnv *env, jclass clazz, const char *name, const char *sig);

这就引入了一个新的问题,什么是sig,我们后面再说,举个例子说明

前提说明: JAVA类TestProvider,该类有2个方法分别为String getTime( ),void saysayHello( String str)

jclass TestProvider;

jobject mTestProvider;

jmethodID getTime;

jmethodID sayHello;

C 中映射类

TestProvider = (*jniEnv)->FindClass(jniEnv,"com/duicky/TestProvider");

C中新建对象

//默认构造函数,不传参数       jmethodID construction_id = (*jniEnv)->GetMethodID(jniEnv, TestProvider,"", "()V");

//通过NewObject来创建对象       jobject mTestProvider = (*jniEnv)->NewObject(jniEnv, TestProvider,construction_id);

C 中映射方法

静态:

getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestProvider, "getTime","()Ljava/lang/String;");

非静态:

sayHello = (*jniEnv)->GetMethodID(jniEnv, TestProvider, "sayHello","(Ljava/lang/String;)V");

C 中调用 Java的 方法

静态:

(*jniEnv)->CallStaticObjectMethod(jniEnv, TestProvider, getTime);

非静态:

(*jniEnv)->CallVoidMethod(jniEnv, mTestProvider, sayHello,jstrMSG);

注意GetXXXMethodID  和 CallXXXMethod 。

第一个XXX 表示的是映射方法的类型,如: 静态 跟非静态

第二个 XXX 表示 调用方法的返回值 ,如:Void,Object,等等。(调用静态方法的时候Call后面要加Static)

5. sign签名

对于jmethodID GetMethodID(jclass clazz, const char *name, const char *sign)

clazz代表该属性所在的类,name表示方法名称,sign是签名

那什么是签名,签名是对函数参数和返回值的描述,对同一个函数,在java中允许重载,这个时候就需要这个sign来进行区分了。

以下是java类型签名的描述

用来表示要取得的属性/方法的类型

类型           相应的签名

boolean        Z

byteB

charC

shortS

intI

longJ

floatF

doubleD

voidV

objectL用/分隔包的完整类名:   Ljava/lang/String;

Array          [签名          [I      [Ljava/lang/Object;

Method         (参数1类型签名 参数2类型签名···)返回值类型签名

特别注意:Object后面一定有分号(;)结束的,多个对象参数中间也用分号(;)来分隔

例子:

方法签名

voidf1()                         ()V

intf2(int,long)                 (IJ)I

boolean f3(int[])                 ([I)B

doublef4(String,int)            (Ljava/lang/String;I)D

voidf5(int, String [],char)    (I[Ljava/lang/String;C)V

图解签名:

使用javap命令来产生签名

javap -s -p [full class Name]

-s 表示输出签名信息

-p 同-private,输出包括private访问权限的成员信息

例子:

C:\E\java\workspaces\myeclipseblue\JNITest\bin>javap -s -private video1.TestNative

Compiled from "TestNative.java"

public class video1.TestNative extends java.lang.Object{

public java.lang.String name;

Signature: Ljava/lang/String;

public video1.TestNative();

Signature: ()V

public int signTest(int, java.util.Date, int[]);

Signature: (ILjava/util/Date;[I)I

public native void sayHello();

Signature: ()V

public static void main(java.lang.String[]);

Signature: ([Ljava/lang/String;)V

}

TestNative完整代码:

package video1;

import java.util.Date;

public class TestNative {

public String name="Test";

public int number =100;

public int signTest(int i,Date date,int[] arr){

System.out.println("Sign Test");

return 0;

}

//native关键字修饰的方法,其内容是C/C++编写的,java中不必为它编写具体的实现    public native void sayHello();

public static void main(String[] args) {

System.loadLibrary("NativeCode");

TestNative tn = new TestNative();

tn.sayHello();

}

}

C/C++代码

#include "video1_TestNative.h"

#include

using namespace std;

JNIEXPORT void JNICALL Java_video1_TestNative_sayHello(JNIEnv * env, jobject obj){

cout<

//因为test不是静态函数,所以传进来的就是调用这个函数的对象//否则就传入一个jclass对象表示native()方法所在的类    jclass native_clazz = env->GetObjectClass(obj);

//得到jfieldID    jfieldID fieldID_prop = env->GetFieldID(native_clazz,"name","Ljava/lang/String;");

jfieldID fieldID_num = env->GetFieldID(native_clazz,"number","I");

//得到jmethodID    jmethodID methodID_func=env->GetMethodID(native_clazz,"signTest","(ILjava/util/Date;[I)I");

//调用signTest方法    env->CallIntMethod(obj,methodID_func,1L,NULL,NULL);

//得到name属性    jobject name = env->GetObjectField(obj,fieldID_name);

//得到number属性    jint number= env->GetIntField(obj,fieldID_num);

cout<SetIntField(obj,fieldID_num,18880L);

number= env->GetIntField(obj,fieldID_num);

cout<

本文地址,转载请注明出处:

参考资料:

jni.h 头文件:

相关例子:

Programmming in C/C++ with the Java Native Interface (3 个练习)

JNI 文档:

基于 Android NDK 的学习之旅----- C调用Java

Linux下JNI的使用:比较基础

如何在Android下使用JNI:讲解比较详细,但是代码里有些错误,空格没处理好

这篇文章有些地方不清楚的参考下这篇文章

Android Jni代码示例讲解

其他推荐学习网站

使用 Java Native Interface 的最佳实践:描述了JNI性能和缓存的一些东西

JNI 攻略系列

JNI Examples for Android

JNI pthread 多线程使用

jni 调用java类方法_AndroidJNI 通过C++调用JAVA相关推荐

  1. java类方法不可见_使java方法仅对特定类可见

    我有一个经理类负责管理某种对象.要做到这一点,它需要操纵这些对象,但这些对象与管理器无关,所以从技术上讲,它们位于单独的包"project.managers"和"proj ...

  2. java在主程序修改函数输出,Java通过JNI调用CUDA

    --NG 这段时间因为工作需要,要用到在java中调用cuda程序,但是令人蛋疼的是网上这方面的资料几乎没有,所以只好我自己摸索.我的想法是通过java的JNI接口调用cuda,但是很明显正常情况下是 ...

  3. java JNI调用C语言动态链接库(java.lang.UnsatisfiedLinkError: no yourClassName in java.library.path 异常的解决方法)

    转自: http://watershitter.iteye.com/blog/477615 今天花了至少3个小时跑这个java调c的动态链接库的Hello,native world的程序.  把所有犯 ...

  4. jni c java互相调用_通过JNI实现Java和C++的相互调用

    评论 # re: 通过JNI实现Java和C++的相互调用 2008-07-29 14:14 Always BaNg. 不错,把字符转换也一并讲了吧,比如UTF-8的处理,USC-2与MBCS转换等. ...

  5. cocos2d-x 调用java_cocos2d-x中通过Jni实现Java与C++的互相调用

    cocos2d-x中通过Jni实现Java与C++的互相调用. cocos2d-x用开发者提供了一个类JniHelper,提供了java与c++之间互调的jni解决方案. 笔者所开发的"史上 ...

  6. Android JNI实现Java与C/C++互相调用,以及so库的生成和调用(JNI方式调用美图秀秀so)

    前言 关于Android Studio如何继承JNI开发环境,请阅读上一篇博文 Android CMake集成JNI开发环境本篇博文将结合实例分别讲解Android中Java如何调用C/C++的方法, ...

  7. java 实例方法直接调用超类的实例方法_类方法和实例方法的调用 super this 访问控制符...

    一.类方法和实例方法的调用 先看一道选择题: 下列哪种说法是正确的( ) A. 实例方法可直接调用超类的实例方法 B. 实例方法可直接调用超类的类方法 C. 实例方法可直接调用其他类的实例方法 D. ...

  8. beetl调用java方法_08.自定义方法以及直接访问java类方法---《Beetl视频课程》

    本期视频实现了发布评论时间自定义显示: 内容简介:使用了自定义方法以及直接访问java方法实现了发布时间自定义显示 作者:GK 自定义方法 我们想要实现类似于${ strutil.subString ...

  9. Java——this关键字(调用本类属性、调用本类方法、表示当前对象)

    目录 1.调用本类属性 2.调用本类方法 3.表示当前对象 this是一个非常灵活的关键字,不会明确表示一个固定概念,比如int,它就是表示一个整型. 1.调用本类属性 类中有许多成员,大部分情况下类 ...

  10. java 类方法和实例方法 调用关系

    java 类方法和实例方法 1. 类方法 也可称静态方法,使用static修饰的类中方法: 2.实例方法 非静态方法,没有用static修饰的方法. 3.测试案例 public class Test ...

最新文章

  1. Foxmail邮件如何导入Outlook中
  2. 【Python小程序】必备软件系列之文字识别提取,前台再也不同担心纸质转电子文件啦~
  3. 防止mysql拷贝_转载:mysql复制优化
  4. 查一个字段中字符集超过30的列_详细解读MySQL的30条军规
  5. mb_internal_encoding php,PHP字符串mbstring处理中文字符串的具体方法解析
  6. 通过Intel XDK编写跨平台app(一)
  7. Java面试官最爱问的垃圾回收机制,Java编程配置思路详解
  8. 1631. 最小体力消耗路径
  9. Xcode真机调试中“There was an internal API error“错误解决方法
  10. 读《scikiit-learn机器学习》黄永昌第四章
  11. WIN7下IIS的安装与配置
  12. Java web技术及应用答案_超星《Java Web应用开发技术》答案
  13. paip.c#.net未能找到任何资源
  14. yml在线格式转换工具
  15. 冷暖自知 who knew:伤感日志
  16. 从 Uber 数据泄露事件我们可以学到什么?
  17. JS中字符串的创建、操作及其方法
  18. 一个int类型到底占多少个字节
  19. Linux查看系统信息命令总结
  20. dlib.get_frontal_facedetector UINT8 和float格式互相转换

热门文章

  1. 逐步揭示makop.mkp勒索病毒中毒防范恢复解密
  2. cubemx6.0配置touchgfx 正点原子触摸屏,touchgfx添加触摸驱动
  3. 安卓10源码开发定制(30)screencap命令源码分析
  4. 桌面运维转网络要做什么准备,高级网工学习路线分享
  5. 计算机桌面维护的相关知识,电脑维护知识
  6. ERP : 服装行业解决方案
  7. java图片转为矢量文件_java 通过batik 把svg格式的矢量图生成png图片
  8. Android音频播放之SoundPool 详解
  9. 操作系统 | 内存文件映射 —— 文件到内存的映射
  10. 完整制作个人博客系统