JNI用C构建复杂对象并返回

1 篇文章 0 订阅
1 篇文章 0 订阅

JNI用C构建复杂对象并返回

JAVA类

  1. Account.java
  2. Person.java
  3. PersonManager.java
  4. PersonTest.java

C文件

  1. PersonManager.cpp
  2. jni_PersonManager.h
  3. jni.h
  4. jni_md.h

PS:jni.h和jni_md.h在jdk的include文件下

文件关系以及实现目标

  • Account为普通的java类
  • Person中有一个属性为Account(对象内嵌套对象)
  • 目的:使用jni构建Person以及Account对象,然后调用set方法把Account赋给Person并返回
    - Person内含有Account属性,通过调用C来构建Person对象并返回接收

遇到的问题

  1. 直接用给参数赋值的方法给对象参数赋值不成功,需要添加set方法并通过C调用set方法
    2. 在C中获取set方法时提示找不到该方法,当方法参数为自定义对象时不能用"(jni/Account;)V"这个方法签名,需要使用"(Ljava/lang/Object;)V"然后在java中定义形参类型为Object,然后在赋值时强转为对应所需要的类型
  2. **

查看方法签名很重要

使用 javap -s Person.class命令解析出该类中方法的方法签名 然后把签名复制到c中

**
4. 把java jni类编译为头文件时,如果该文件内引用了其他类,需要用 javac *java -h jni命令全部编译,不然会报找不到类的错误

详细代码实现
Account.java

package jni;
public class Account {
	public int usrname;
	public String password;
}

Person.java

package jni;
public class Person {
	public String name;
	public int age;
	public Account account;
	public Account getAccount() {
		return account;
	}
	public void setAccount(Account account) {
		this.account = account;
	}
}

PersonManager.java

package jni;
public class PersonManager {
	static {
		System.load("C:\\Users\\User\\source\\repos\\Dll5\\x64\\Debug\\Dll5.dll");
	}
	public native static String test();
	public native static Person getPerson();  
}

PersonTest.java

package jni;
public class PersonTest {
	public static void main(String[] args) {
		System.out.println(PersonManager.test());
		Person p= PersonManager.getPerson();
		System.out.println("p.name="+p.name);
		System.out.println("p.age="+p.age);
		if(p.account!=null) {
			System.out.println("p.account.usrname="+p.account.usrname);
			System.out.println("p.account.password="+p.account.password);
		}
	}
}
jni_PersonManager.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class jni_PersonManager */

#ifndef _Included_jni_PersonManager
#define _Included_jni_PersonManager
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jni_PersonManager
 * Method:    test
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_jni_PersonManager_test
  (JNIEnv *, jclass);

/*
 * Class:     jni_PersonManager
 * Method:    getPerson
 * Signature: ()Ljni/Person;
 */
JNIEXPORT jobject JNICALL Java_jni_PersonManager_getPerson
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif
PersonManager.cpp
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "pch.h"
#include "jni.h"
#include "jni_PersonManager.h"
	/*
	 * Class:     jni_PersonManager
	 * Method:    test
	 * Signature: ()Ljava/lang/String;
	 */
JNIEXPORT jstring JNICALL Java_jni_PersonManager_test(JNIEnv *env, jclass cls) {
	return env->NewStringUTF("Hello");
	}

	/*
	 * Class:     jni_PersonManager
	 * Method:    getPerson1
	 * Signature: ()Ljni/Person;
	 */
JNIEXPORT jobject JNICALL Java_jni_PersonManager_getPerson(JNIEnv *env, jclass cls) {


	/*
	* account类的信息获取
	*/
	jclass    m_cls_a = env->FindClass("jni/Account");

	jmethodID m_mid_a = env->GetMethodID(m_cls_a, "<init>", "()V");

	/*
	* account类指定变量名和类型
	*/
	jfieldID  m_fid_a_1 = env->GetFieldID(m_cls_a, "usrname", "I");
	jfieldID  m_fid_a_2 = env->GetFieldID(m_cls_a, "password", "Ljava/lang/String;");

	/*
	* account类创建对象
	*/
	jobject m_obj_a = env->NewObject(m_cls_a, m_mid_a);

	/*
	* account类对象变量赋值
	*/
	env->SetIntField(m_obj_a, m_fid_a_1, 123456);
	env->SetObjectField(m_obj_a, m_fid_a_2, env->NewStringUTF("pwd1"));

	/*
	* person类的信息获取
	*/
	jclass    m_cls_p = env->FindClass("jni/Person");

	jmethodID m_mid_p = env->GetMethodID(m_cls_p, "<init>", "()V");

	/*
	* person类指定变量名和类型
	*/
	jfieldID  m_fid_p_1 = env->GetFieldID(m_cls_p, "name", "Ljava/lang/String;");
	jfieldID  m_fid_p_2 = env->GetFieldID(m_cls_p, "age", "I");

	/*
	* person类获取setAccount方法id
	*/
	jmethodID setAccountId = env->GetMethodID(m_cls_p, "setAccount","(Ljni/Account;)V");


	/*
	* person类创建对象
	*/
	jobject   m_obj_p = env->NewObject(m_cls_p, m_mid_p);
	/*
	* person类对象变量赋值
	*/
	env->SetObjectField(m_obj_p, m_fid_p_1, env->NewStringUTF("xiaoming"));
	env->SetIntField(m_obj_p, m_fid_p_2, 26);

	/*
	* 调用person的setAccount方法
	*/
	//int result = 50;
	//if (setAccountId!=0) {
	//	result= env->CallIntMethod(m_obj_p,setAccountId);
	//}
	
	if (setAccountId != 0) {
		env->CallVoidMethod(m_obj_p, setAccountId,m_obj_a);
	}
	return m_obj_p;
	}

java传String到c++

jstring sIp;(传过来的参数)
const char *str;
str=env->GetStringUTFChars(sIp,false)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值