惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
O
OpenAI News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Google Online Security Blog
Google Online Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
N
News and Events Feed by Topic
S
Security Affairs
SecWiki News
SecWiki News
Project Zero
Project Zero
L
Lohrmann on Cybersecurity
P
Proofpoint News Feed
P
Palo Alto Networks Blog
L
LINUX DO - 最新话题
H
Hacker News: Front Page
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
Intezer
Simon Willison's Weblog
Simon Willison's Weblog
W
WeLiveSecurity
T
The Exploit Database - CXSecurity.com
K
Kaspersky official blog
The GitHub Blog
The GitHub Blog
I
InfoQ
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
B
Blog
IT之家
IT之家
AWS News Blog
AWS News Blog
Jina AI
Jina AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Google DeepMind News
Google DeepMind News
Spread Privacy
Spread Privacy
N
News and Events Feed by Topic
Security Latest
Security Latest
美团技术团队
C
Check Point Blog
WordPress大学
WordPress大学
T
Tenable Blog
S
Security @ Cisco Blogs
Last Week in AI
Last Week in AI
博客园 - 聂微东
月光博客
月光博客
博客园 - 【当耐特】
S
Schneier on Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Secure Thoughts
Schneier on Security
Schneier on Security
C
Cisco Blogs
Cyberwarzone
Cyberwarzone

博客园 - 星辰之力

网站工具 Vue项目用于Ios和Android端开发 Android assets文件夹之位置放置和作用 轻松搭建Xposed Hook cordov vue项目中调用手机原生api Android 直接修改dex破解 Android 逆向实战篇(加密数据包破解) Android JNI中C调用Java方法 Android Studio NDK JNI动态注册本地方法 JNI C反射调用java方法 JNI NDK (AndroidStudio+CMake )实现C C++调用Java代码流程 Jni 线程JNIEnv,JavaVM,JNI_OnLoad(GetEnv返回NULL?FindClass返回NULL?) Jni OnLoad()和OnUnload() Android NDK编译之undefined reference to 'JNI_CreateJavaVM' Android 开创java世界(JNI Invocation API) Android JNI c/c++调用java 无需新建虚拟机 cmake:善用find_package()提高效率暨查找JNI支持 如何解决用CMake未定义引用`JNI_CreateJavaVM'? [Linker error] undefined reference to `_imp__JNI_CreateJavaVM@12'
Android JNI之C/C++层调用JAVA
星辰之力 · 2019-03-27 · via 博客园 - 星辰之力

从C/C++层调用JAVA层代码步骤:

1. 在JAVA类中创建java方法和本地方法

public class TestNdk{
int a;//本示例中将被修改的JAVA变量 Handler handler;
public TestNdk(Handler handler){ this.handler = handler; setUp(); } public native void setUp();//本地方法 public native static int getStringFromNative();//本地方法 public int getA() { return a; } public native void setA(int a);//本地方法 public void notifyFiledChange(){//本示例中将被C/C++调用的JAVA方法 Message message = new Message(); Bundle bundle = new Bundle(); bundle.putInt("a",a); message.setData(bundle); message.what=1; handler.sendMessage(message); } static { System.loadLibrary("MyJni");//导入生成的链接库文件 } }

2.在JNI文件夹下创建类对应的.h文件(可通过JAVAH命令生成该类的.h文件,就不赘述了),创建.cpp文件(用于编写C/C++层的代码)

.h文件:

#ifndef _Included_com_x_mp4player_TestNdk
#define _Included_com_x_mp4player_TestNdk
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_x_mp4player_TestNdk
 * Method:    setUp
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp
  (JNIEnv *, jobject);

/*
 * Class:     com_x_mp4player_TestNdk
 * Method:    setA
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setA
        (JNIEnv *env, jobject thiz,jint i);

/*
 * Class:     com_x_mp4player_TestNdk
 * Method:    getStringFromNative
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_x_mp4player_TestNdk_getStringFromNative
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

.cpp文件

#include <jni.h>
#include <com_x_mp4player_TestNdk.h>

jobject m_object;
jmethodID m_mid;
jfieldID m_fid;

JNIEXPORT jint JNICALL Java_com_x_mp4player_TestNdk_getStringFromNative
        (JNIEnv *env, jclass cls) {
    return 1;
}

JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp
        (JNIEnv *env, jobject thiz) {
    jclass clazz = (*env).GetObjectClass(thiz);//获取该对象的类
    m_object = (*env).NewGlobalRef(thiz);//创建对象的本地变量
    m_mid =(*env).GetMethodID(clazz, "notifyFiledChange", "()V");//获取JAVA方法的ID
    m_fid = (*env).GetFieldID(clazz,"a","I");//获取java变量的ID
    return;
}

JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setA
        (JNIEnv *env, jobject thiz,jint i) {
    (*env).SetIntField( m_object, m_fid,i);
    (*env).CallVoidMethod(m_object,m_mid);
    return;
}

3.调用JAVA方法需要类的对象

在C/C++层获取类的对象的方法有两种:

  • 通过JAVA层调用本地方法(如示例中的setUp()方法),在调用时,会传入对象jobject或者对象的类jclass

JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp
        (JNIEnv *env, jobject thiz) {
    ...
    jclass clazz = (*env).GetObjectClass(thiz);//获取该对象的类
    ...
    return;
}
  • 通过C/C++创建java对象

方法如下:

1.通过JAVA层的本地方法创建同类对象

步骤:

I.通过对象获取类

II.通过类获取类的构造方法的ID

III.基于方法ID和类,创建新对象

JNIEXPORT void JNICALL JAVA_nativeMethod
        (JNIEnv *env, jobject thiz,jint i){
    ...
    jclass clazz = (*env).GetObjectClass(thiz);
    jmethodID mid = (*env).GetMethodID(clazz,"<init>","()V");
    jobject obj = (*env).NewObject(clazz,mid);
    ...
    return;
}

2.通过C/C++创建不同类对象

步骤:

I.通过FindClass方法获取需要的类

II.通过类获取类的构造方法的ID

III.基于方法ID和类,创建新对象

JNIEXPORT void JNICALL JAVA_nativeMethod
        (JNIEnv *env, jobject thiz,jint i){
    ...
    jclass clazz = (*env).FindClass("com/x/test/Test");//参数为类路径
    jmethodID mid = (*env).GetMethodID(clazz,"<init>","()V");
    jobject obj = (*env).NewObject(clazz,mid);
    ...
    return;
}

3.通过C++直接创建

4.调用java方法的步骤:

  1. 获取类的方法ID
  2. 基于对象和方法id调用JAVA方法

  • 示例中是java调用本地方法setUp后,调用本地方法setA(int i),在本地方法setA(int i)中调用JAVA方法notifyFiledChange()方法

5.C/C++直接存取JAVA变量

  1. 获取对象的变量的ID
  2. 基于对象和变量id存取变量