c++通过jni回调给java (如何获取env)_c++ jnienv_半夏茶白的博客-程序员秘密

技术标签: jni  

java代码

package com.example.testpackage android.util.Log;
public class Test {
    
// 加载jni
static {
    
	try {
    
		System.loadLibrary(“healthmonitor_jni”);
	} catch (SecurityException ex) {
    
		Log.e(TAG,System.loadLibrary SecurityException+ ex);
	} catch (NullPointerException ex) {
    
		Log.e(TAG,System.loadLibrary NullPointerException+ ex);
	} catch (UnsatisfiedLinkError ex) {
    
		Log.e(TAG,System.loadLibrary UnsatisfiedLinkError+ ex);
	}
}

public Test () {
    
    Log.d(TAG, "Test construct");
    // 调用jni接口
    native_register();
}

public static void TestCallBack(int a, int b) {
    
	// to do something ...
}

// 声明jni接口
private native void native_register();
private native void native_release();
}

jni代码

#include <jni.j>
#include <stdio.h>
#include <nativehelper/JNIHelp.h>
#include <Utils/Log.h>

#define JAVA_CLASSNAME_TEST "com.example.test.Test"

using namespace std;
using namespace android;

static JavaVM *mJvm;
static jclass mClazz;
static jmethodID mCallbackMethod;

// 通过JavaVM 获取JNIEnv 
// android 源码通过JNIEnv *env = AndroidRuntime::getJNIEnv(),自己写的jni由于ndk的制限,
// 使用该方式获取到的env为null
static JNIEnv *get_env() {
    
	if (mJvm == NULL) return NULL;
	JNIEnv *env = NULL;
	
	int status = mJvm->GetEnv((void**) &env, JNI_VERSION_1_4);
	if (status == JNI_EDETACHED || env == NULL) {
    
	    status = mJvm->AttachCurrentThread(&env, NULL);
	    if (status < 0) {
    
	        env = NULL;
	    }
	}
	return env;
}

static void com_example_callback(int a, int b) {
    
	JNIEnv *env = get_env();
	env->CallStaticVoidMethod(mClazz, mCallbackMethod , 
	a, b);
}

static void com_example_register(JNIEnv *env, jobject thiz) {
    
	// 调用c++ register() 函数, mTest为c++类对象
	mTest->register(com_example_callback);
}

static void com_example_release(JNIEnv *env, jobject thiz) {
    
	//不需要使用的时候,不要忘记释放全局引用
	(*mJvm)->DetachCurrentThread(*mJvm);
	(*mJvm)->DestroyJavaVM(mJvm);
	return 0;
}
static JNINativeMethod sMethods[] = {
    
{
    “native_register”,()V”, (void )com_example_register}
{
    “native_release”,()V”, (void )com_example_release}
};

// This function only registers the native methods
static int register_HealthMonitor_jni(JNIEnv *env) {
    
	return jniRegisterNativeMethods(env, JAVA_CLASSNAME_HEALTHMONITOR, 
	sMethods, NELEM(sMethods));
}

// 可以不重写该函数,会使用默认
jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
    
	mJvm = vm;
	JNIEnv env = NULL;
	jint result = -1;
	jclass tmpClazz  = NULL;

	if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
    
	    goto bail;
	}
	assert(env != NULL);
	
	// 通过FindClass获取的jclass 并不是一个实例,只能回调静态方法
	// 回调非静态方法需要通过jclass clazz = env->GetObjectClass(obj)获取jclass,
	// 调用GetMethodID 获取 jmethodID 
	// 调用CallVoidMethod()回调给 java
	tmpClazz = env->FindClass(JAVA_CLASSNAME_HEALTHMONITOR);
	// 直接使用tmpClazz 会导致crash-->jni error (app bug): accessed stale local reference
	mClazz = (jclass)env->NewGlobalRef(tmpClazz);
	mCallbackMethod = env->GetStaticMethodID(mClazz, “TestCallBack”,(II)V”);
	
	if (register_HealthMonitor_jni(env) < 0) {
    
	    goto bail;
	}

	/* success -- return valid version number */
	result = JNI_VERSION_1_4;
	
	bail:
	return result;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/amin_hui/article/details/115559374

智能推荐

tensorRT教程——使用tensorRT OP 搭建自己的网络_tensort 编写自己网络_TigerZ*的博客-程序员秘密

如下提供一个可以运行的使用tensorRT的OP来搭建自己定义的层或者直接重写自己网络,使用OP的场景: 1、自己的网络无法通过paser来直接转换为TRT的网络。如果自己写cuda实现,那么量化的操作也得自己实现,这样难度其实很高,建议还是使用TRT的OP搭建,搭建完支持量化等操作。 2、学习测试TRT的OP。 关于OP的一些我遇到的疑惑解读见我的另一篇博客:https://blog.csdn.net/u012863603/articl...

luogu P3765 总统选举(线段树维护摩尔投票+平衡树)_Aaronliu17008的博客-程序员秘密

这题需要一个黑科技——摩尔投票。这是一个什么东西?一个神奇的方法求一个序列中出现次数大于长度一半的数。简而言之就是同加异减;比如有一个代表投票结果的序列。\[[1,2,1,1,2,1,1]\]我们记录一个\(num\)和\(cnt\)先别管它们是干什么的。我们模拟一遍模拟排序。\[首先读第一个数1,num==0,我们把cnt+1=1,num=1\]\[第二个数2,num==1...

一小时搞明白注解处理器(Annotation Processor Tool)_annotationprocessorpaths_顾明伟的博客-程序员秘密

Java中的注解是个很神奇的东西,还不了解的可以看下一小时搞明白自定义注解(Annotation)。现在很多Android的库都用使用注解实现的,比如ButterKnife,我们不防也来学习一下,学完注解处理器,我们尝试写一个简单的类似ButterKnife的东西来绑定控件。什么是注解处理器?        注解处理器是(Annotation Processor)是javac的一个工具,用来在编译

2021年,DevOps的7个发展趋势_程序员小乐的博客-程序员秘密

点击上方 &#34;编程技术圈&#34;关注,星标或置顶一起成长后台回复“大礼包”有惊喜礼包!每日英文Instead of giving yourself reasons why you...

生产数据库、开发数据库、测试数据库中的数据的区分_tottoramen的博客-程序员秘密

在我们理解了数据库的概念以后,我们在实际应用的过程中还会听到到生产数据库这样子的名词,那门多了生产两个字到底是什么意思呢?其实这些都是依据数据库的作用不同人们起的不同的名字罢了。底层的原理是一样的。可以这样简单理解:生产数据库:业务实际使用的数据库。简称生产库查询库:也有查询库这样子的叫法,这是给程序调用或者人工查询数据使用的,和生产库在内容上不会有差异。唯一不同就是访问的DG镜像库。生产库是主库。这样做是可以分散单数据库的访问压力,提高效率,同时本身也是很好的防灾手段。开发数据库:供系

Office2019 安装MathType7.4.4 解决找不到MathPage.wll问题_找个地方说说话的博客-程序员秘密

系统环境win10部分Office2019正常安装MathType7.4.4后仍会出现找不到mathpage.wll的错误mathtype可从这里获取https://miraclenet.ax.lt/index.php/2019/08/29/mathtypechsspecialwin/安装完成后,判断Office是32位还是64位方法:Word-帐户-关于Word ,可以看到位...

随便推点

签了工作之后才发现,自己太草率了.....我看过的关于职业规划最好最全面的一篇文章..._weixin_30914981的博客-程序员秘密

在担任公司高管的几年间,我面试过数以百计的各个层面的员工,其中最让我感到遗憾的一个现象就是很多人有着非常好的素质,甚至有的还是名校的毕业生,因为不懂得去规划自己的职业,在工作多年后,依然拿着微薄的薪水,为了一份好一点的工作而奔波。很多这样的人,他们只要稍微修正一下自己的职业方向,就能够在职业发展上走得更从容。有一次一个大连理工大学的研究生,好像是学电子的,来应聘我们的公关企划部部长。那小伙长得...

GPS经纬度及谷歌地图坐标转换为百度地图坐标,解决地图显示经纬度的偏移问题_yx0628的博客-程序员秘密

最近做项目中遇到的一个问题,即测量得到的经纬度值在百度地图上出现了偏移,是所有经纬度点整体的偏移,上网搜了,得知如下的情况:       国内出版的各种地图系统(包括电子形式),必须至少采用GCJ-02对地理位置进行首次加密。国际经纬度坐标标准为WGS-84,国内必须至少使用国家测绘局制定的GCJ-02对地理位置进行首次加密。百度地图在此基础上,进行了BD-09二次加密措施,因此百度地图对外接

007--C++构造析构对于栈区堆区的顺序(最优)_码字界陈冠希的博客-程序员秘密

简介:栈区对象由系统自动释放,但堆区(动态内存建立的对象)对象由程序员自己手动释放。因此,建立一个对象,由于它所建立的方式,即栈区建立或则堆区建立,导致其对象的构造析构顺序不同。代码学习区://只需要给出实体对象,自动调用构造函数。//栈区的对象,先构造的后析构,后构造的先析构。//堆区的对象,先构造的先析构,后构造的后析构。#include&lt;iostream&gt;using namespace std;class A{public: A(){ cout &lt;&.

SQL getdate() 格式的具体应用_jay_0215的博客-程序员秘密

Sql Server 中一个非常强大的日期格式化函数Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AMSelect CONVERT(varchar(100), GETDATE(), 1): 05/16/06Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16

Unity添加可拉伸的图片_unity 图片拉伸_newchenxf的博客-程序员秘密

创建首先,把图片放到Assets目录下(可以是Assets下的子目录)。然后打开Unity,发现它非常敏捷的发现了图片,并在同一个生成了meta文件,但这我们不用关心,只要知道Unity发现了你的图片了。这时候,在Project面板,选中刚才加的图片:这时候,Inspector面板会显示图片信息。[Texture Type]从Default改为Sprite(2D and UI)。这代表图片可以作为2D UI切图了。然后点击Sprite Editor,可以编辑图片。出来的窗口如下:共有四个

2021-08-12 2021年金属非金属矿山安全检查(地下矿山)考试报名及金属非金属矿山安全检查(地下矿山)实操考试视频_zbf123123的博客-程序员秘密

题库来源:安全生产模拟考试一点通公众号小程序金属非金属矿山安全检查(地下矿山)考试报名参考答案及金属非金属矿山安全检查(地下矿山)考试试题解析是安全生产模拟考试一点通题库老师及金属非金属矿山安全检查(地下矿山)操作证已考过的学员汇总,相对有效帮助金属非金属矿山安全检查(地下矿山)实操考试视频学员顺利通过考试。1、【单选题】在冒顶事故抢救处理过程中必须有专人检查与监视( )情况,以免再次发生冒顶事故。( A )A、顶板B、通风系统C、电力照明2、【单选题】对可能发生急性职业损伤的有毒、有害工作