转 java c++互传arraylist
Java JNI由浅入深(包括:Java和C++互传ArrayList泛型对象参数)
我们知道Java是一个运行在虚拟机里面的高级的编程语言,如果要调用系统的动态链接库的话,就要先声明native修饰的方法(类似接口里面的方法),再由C/C++程序来实现(类似实现接口里的方法)。这样Java调用这些native方法就相当于调用了C/C++里面实现了的方法。通常我们把这种机制叫做JNI(Java NativeInterfac),即Java 本地编程接口
Android也同理,要学会在Android上进行NDK开发,首先我们到打好java JNI的基础。现在我们暂时把Android开发丢到一边先,试试在Java之下编译一个C动态链接库,再用Java程序调用。
1)先来个最简单的打印HelloWorld例子:
Java代码(HelloJni.java):
- import java.util.*;
- public class HelloJni{
- static{
- System.loadLibrary("hello");
- }
- public native static void sayHello();
- public static void main(String [] args)
- {
- HelloJni.sayHello();
- }
- }
生成头文件(HelloJni.h):
先javac HelloJni.java编译你的Java源码,再javah–jni HelloJni生成所需的头文件
头文件内容是这样的:
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- /* Header for class HelloJni */
- #ifndef _Included_HelloJni
- #define _Included_HelloJni
- #ifdef __cplusplus
- extern "C" {
- #endif
- JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);
- #ifdef __cplusplus
- }
- #endif
- #endif
实现头文件声明的方法(HelloJni.cpp)
- #include "HelloJni.h"
- JNIEXPORT void JNICALL Java_HelloJni_sayHello(JNIEnv *env, jclass cls)
- {
- printf("HelloWorld");
- }
编译命令: g++ -I$JAVA_HOME/include-I$JAVA_HOME/include/linux HelloJni.cpp -shared -o libhello.so
命令参数解析:-I 是指引入java虚拟机的库的路径,-shared 是指编译成动态链接库(共享库) –o 输出文件名(注意,在Linux平台下的动态链接库有一个命名格式:“lib+库名+.so”在java代码里面loadLibrary的时候不要加lib前缀和.so后缀)
由于我这里把这个动态链接库编译放在当前目录下,所以还要设置环境变量LD_LIBRARY_PATH=该so动态链接库所在的目录,才能正常运行
#############################+++华丽的分割线+++###########################
2)好了,可以打印HelloWorld出来后,我们再深入一点点,传入一个int的数,在C/C++代码里面加1后返回。
Java代码(HelloJni.java):
- public class HelloJni{
- static{
- System.loadLibrary("hello");
- }
- public static native void sayHello();
- public native int getInt();
- public native void setInt(int i);
- public static void main(String args[]){
- // HelloJni.sayHello();
- HelloJni hello = new HelloJni();
- hello.setInt(2);
- System.out.println(hello.getInt());
- }
- }
生成头文件(HelloJni.h):
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- /* Header for class HelloJni */
- #ifndef _Included_HelloJni
- #define _Included_HelloJni
- #ifdef __cplusplus
- extern "C" {
- #endif
- JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);
- JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);
- JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);
- #ifdef __cplusplus
- }
- #endif
- #endif
实现头文件声明的方法(HelloJni.cpp)
- #include "HelloJni.h"
- int i=1;
- JNIEXPORT void JNICALL Java_HelloJni_sayHello
- (JNIEnv *env, jclass cls){
- printf("HelloWorld/n");
- }
- JNIEXPORT jint JNICALL Java_HelloJni_getInt
- (JNIEnv *env, jobject thiz){
- return i;
- }
- JNIEXPORT void JNICALL Java_HelloJni_setInt
- (JNIEnv *env, jobject thiz,jint ji){
- i = ji+1;
- }
运行结果:打印2
3)只是传入简单的数据类型不爽,这次让C/C++生成个Java对象返回
Java代码:pojo实体类(User.java)
- public class User{
- private long id;
- private String userName;
- private boolean isMan;
- private int age;
- public User(){}
- public User(long id, String userName, boolean isMan, int age) {
- super();
- this.id = id;
- this.userName = userName;
- this.isMan = isMan;
- this.age = age;
- }
- public long getId() {
- return id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public boolean isMan() {
- return isMan;
- }
- public void setMan(boolean isMan) {
- this.isMan = isMan;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
Java代码(HelloJni.java):
- public class HelloJni{
- static{
- System.loadLibrary("userbean");
- }
- public static native void sayHello();
- public native int getInt();
- public native void setInt(int i);
- public native void setUser(String userName);
- public native User getUser();
- public static void main(String args[]){
- // HelloJni.sayHello();
- HelloJni hello = new HelloJni();
- // hello.setInt(2);
- // System.out.println(hello.getInt());
- hello.setUser("LiangYaotian");
- User user = hello.getUser();
- System.out.println("user from c/c++");
- System.out.println("name:"+user.getUserName());
- System.out.println("isMan?:"+user.isMan());
- System.out.println("age:"+user.getAge());
- }
- }
生成头文件(HelloJni.h):
- #include <jni.h>
- /* Header for class HelloJni */
- #ifndef _Included_HelloJni
- #define _Included_HelloJni
- #ifdef __cplusplus
- extern "C" {
- #endif
- JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);
- JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);
- JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);
- JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *, jobject, jstring);
- JNIEXPORT jobject JNICALL Java_HelloJni_getUser (JNIEnv *, jobject);
- #ifdef __cplusplus
- }
- #endif
- #endif
实现头文件声明的方法(HelloJni.cpp)
- #include <iostream>
- #include <stdio.h>
- using namespace std;
- int i=1;
- jobject user;
- JNIEXPORT void JNICALL Java_HelloJni_sayHello
- (JNIEnv *env, jclass cls){
- printf("HelloWorld/n");
- }
- JNIEXPORT jint JNICALL Java_HelloJni_getInt
- (JNIEnv *env, jobject thiz){
- return i;
- }
- JNIEXPORT void JNICALL Java_HelloJni_setInt
- (JNIEnv *env, jobject thiz,jint ji){
- i = ji+1;
- }
- JNIEXPORT void JNICALL Java_HelloJni_setUser
- (JNIEnv *env, jobject thiz, jstring name){
- jclass userClass = env->FindClass("User");
- jmethodID userMethod = env->GetMethodID(userClass,"<init>","()V");
- jfieldID mId = env->GetFieldID(userClass,"id","J");
- jfieldID mUserName = env->GetFieldID(userClass,"userName","Ljava/lang/String;");
- jfieldID mIsMan = env->GetFieldID(userClass,"isMan","Z");
- jfieldID mAge = env->GetFieldID(userClass,"age","I");
- jobject userObject = env->NewObject(userClass,userMethod);
- env->SetObjectField(userObject,mUserName,name);
- env->SetLongField(userObject,mId,1001);
- env->SetBooleanField(userObject,mIsMan,1);
- env->SetIntField(userObject,mAge,21);
- user = userObject;
- }
4)有些同学可能会说:“返回个Java对象算什么啊,C/C++和Java之间互传复杂对象才好玩呢!”正所谓“不怕做不到,就怕想不到”,我们接着重构一下上面那个例子!
这次我们传包含有User对象的List到C/C++程序里面
Java代码(User.java)
同上。
Java代码(HelloJni.java)
- import java.util.*;
- public class HelloJni{
- static{
- System.loadLibrary("userbean");
- }
- public native int get();
- public native void set(int i);
- public native void setUser(String userName);
- public native User getUser();
- public native void setUserList(ArrayList<User> userList);
- public native ArrayList<User> getUserList();
- public static void main(String [] args)
- {
- HelloJni hello = new HelloJni();
- // hello.set(2);
- // System.out.println(hello.get());
- /*
- hello.setUser("LiangYaotian");
- User user = hello.getUser();
- System.out.println("user from c/c++");
- System.out.println("name:"+user.getUserName());
- System.out.println("isMan?:"+user.isMan());
- System.out.println("age:"+user.getAge());
- */
- ArrayList<User> userList = new ArrayList<User>();
- for(int i=0;i<10;i++){
- User u = new User((long)(1000+i),"LiangYaotian"+i,true,21);
- userList.add(u);
- }
- hello.setUserList(userList);
- userList = null;
- userList = hello.getUserList();
- System.out.println("ArrayList<User> construct from C++,then Java print it.....");
- for(User u : userList){
- System.out.println("id:"+u.getId()+"; name:"+u.getUserName());
- }
- }
- }
C头文件(HelloJni.h)
- #include <jni.h>
- /* Header for class HelloJni */
- #ifndef _Included_HelloJni
- #define _Included_HelloJni
- #ifdef __cplusplus
- extern "C" {
- #endif
- JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);
- JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);
- JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);
- JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *, jobject, jstring);
- JNIEXPORT jobject JNICALL Java_HelloJni_getUser (JNIEnv *, jobject);
头文件的实现(HelloJni.cpp)
- #include "HelloJni.h"
- int i=1;
- jobject user;
- JNIEXPORT jint JNICALL Java_HelloJni_get
- (JNIEnv *env, jobject jthiz){
- printf("HelloWorld/n");
- }
- JNIEXPORT void JNICALL Java_HelloJni_set
- (JNIEnv *env, jobject jthiz, jint ji){
- i = ji+1;
- }
- JNIEXPORT void JNICALL Java_HelloJni_setUser
- (JNIEnv *env, jobject jthiz, jstring name){
- jclass userClass = env->FindClass("User");
- jmethodID userMethod = env->GetMethodID(userClass,"<init>","()V");
- jfieldID mId = env->GetFieldID(userClass,"id","J");
- jfieldID mUserName = env->GetFieldID(userClass,"userName","Ljava/lang/String;");
- jfieldID mIsMan = env->GetFieldID(userClass,"isMan","Z");
- jfieldID mAge = env->GetFieldID(userClass,"age","I");
- jobject userObject = env->NewObject(userClass,userMethod);
- env->SetObjectField(userObject,mUserName,name);
- env->SetLongField(userObject,mId,1001);
- env->SetBooleanField(userObject,mIsMan,1);
- env->SetIntField(userObject,mAge,21);
- user = userObject;
- }
- JNIEXPORT jobject JNICALL Java_HelloJni_getUser
- (JNIEnv *env, jobject jthiz){
- return user;
- }
- JNIEXPORT void JNICALL Java_HelloJni_setUserList
- (JNIEnv *env, jobject jthiz, jobject userList){
- int i;
- //class ArrayList
- jclass cls_arraylist = env->GetObjectClass(userList);
- //method in class ArrayList
- jmethodID arraylist_get = env->GetMethodID(cls_arraylist,"get","(I)Ljava/lang/Object;");
- jmethodID arraylist_size = env->GetMethodID(cls_arraylist,"size","()I");
- jint len = env->CallIntMethod(userList,arraylist_size);
- printf("get java ArrayList<User> object by C++ , then print it...../n");
- for(i=0;i<len;i++){
- jobject obj_user = env->CallObjectMethod(userList,arraylist_get,i);
- jclass cls_user = env->GetObjectClass(obj_user);
- jmethodID user_getId = env->GetMethodID(cls_user,"getId","()J");
- jmethodID user_getUserName = env->GetMethodID(cls_user,"getUserName","()Ljava/lang/String;");
- jmethodID user_isMan = env->GetMethodID(cls_user,"isMan","()Z");
- jmethodID user_getAge = env->GetMethodID(cls_user,"getAge","()I");
- jstring name = (jstring)env->CallObjectMethod(obj_user,user_getUserName);
- jboolean b = true;
- const char *namePtr = env->GetStringUTFChars(name,&b);
- jlong id = env->CallLongMethod(obj_user,user_getId);
- jboolean sex = env->CallBooleanMethod(obj_user,user_isMan);
- jint age = env->CallIntMethod(obj_user,user_getAge);
- printf("Id:%d; ",id);
- printf("Name:%s; ",namePtr);
- printf("isMan? %d; ",sex);
- printf("Age:%d /n ",age);
- }
- }
- JNIEXPORT jobject JNICALL Java_HelloJni_getUserList
- (JNIEnv *env, jobject jthiz){
- //ArrayList Object
- jclass cls_ArrayList = env->FindClass("java/util/ArrayList");
- jmethodID construct = env->GetMethodID(cls_ArrayList,"<init>","()V");
- jobject obj_ArrayList = env->NewObject(cls_ArrayList,construct,"");
- jmethodID arrayList_add = env->GetMethodID(cls_ArrayList,"add","(Ljava/lang/Object;)Z");
- //User Object
- jclass cls_user = env->FindClass("User");
- //none argument construct function
- jmethodID construct_user = env->GetMethodID(cls_user,"<init>","()V");
- //new a object
- jobject obj_user = env->NewObject(cls_user,construct_user,"");
- //get method id
- /*
- jmethodID user_setId = env->GetMethodID(cls_user,"setId","(J)V");
- jmethodID user_setUserName = env->GetMethodID(cls_user,"setUserName","(Ljava/lang/String;)V");
- jmethodID user_setMan = env->GetMethodID(cls_user,"setMan","(Z)V");
- jmethodID user_setAge = env->GetMethodID(cls_user,"setAge","(I)V");
- */
- int i;
- for(i=0;i<10;i++){
- //new a object
- jobject obj_user = env->NewObject(cls_user,construct_user,"");
- //get field id
- jfieldID user_id = env->GetFieldID(cls_user,"id","J");
- jfieldID user_name = env->GetFieldID(cls_user,"userName","Ljava/lang/String;");
- jfieldID user_isMan = env->GetFieldID(cls_user,"isMan","Z");
- jfieldID user_age = env->GetFieldID(cls_user,"age","I");
- env->SetLongField(obj_user,user_id,i);
- env->SetObjectField(obj_user,user_name,env->NewStringUTF("LiangYaoTian"));
- env->SetBooleanField(obj_user,user_isMan,1);
- env->SetIntField(obj_user,user_age,21);
- env->CallObjectMethod(obj_ArrayList,arrayList_add,obj_user);
- }
- return obj_ArrayList;
- }
运行结果:
转载于:https://www.cnblogs.com/qinjunni/archive/2012/02/20/2359181.html
转 java c++互传arraylist相关推荐
- java处理表单变量_jsp处理表单及JS和JAVA变量互传
1:超连接跳转 我们在超连接的时候,常常连接到一个jsp或者Action,比如: XXX 这样做会有一个问题:在test.jsp中,除你传递的param1和param2参数外,你用request.ge ...
- servlet传参给jsp和js与java变量互传(废弃,建议JSP开发使用jstl)
前端.后端.和js脚本数据交互 1.servlet传参数到jsp页面 1.1 servlet页面发送参数 1.2 jsp页面接收参数 2.jsp页面传参数给servlet 2.1 jsp页面提交参数 ...
- ajax与java后端互传数据
文章目录 后端传到前端(传一个集合,展示成表格) controller层 js部分 前端 向后端传值 js部分 controller层 后端传到前端(传一个集合,展示成表格) controller层 ...
- java通过无wifi传数据_没有数据线?使用WiFi实现电脑手机互传文件
电脑和手机相互传文件是我们常常要做的事情,但都大多依靠数据线来完成.然而,当数据线不在身边或坏了怎么办?这时我们就得想其他的办法了,为此,聪明的网友想到了使用WiFi来实现电脑手机互传文件,而事实上也 ...
- Android向:实现同一局域网内两台手机之间的文件互传
背景 最近要做一个demo,目的是实现局域网内的两台手机之间的文件互传.具体流程如下: 手机 A 从服务器上下载一个 apk 文件到本机上: 手机 A 在自己的某个端口上启动一个 Server 服务, ...
- 阿里云 oss 同区域不同桶名的文件互传
理解:发现阿里云不支持同区域的桶的文件互传,阿里云只支持不同区域的桶文件互传. 同区域,在新加坡创建两个桶,a桶.b桶,想把a桶的文件传到b桶里面以下能实现. @Slf4j public class ...
- Socket实现文件互传(一)
最近一直在做比赛的一个项目,实现客户端和PC端的文件互传,其实一开始在看到这个题目的时候,完全不知道怎么去实现,感觉一脸懵逼,后来在查阅了资料以及相关书籍后了解到可以用Socket来进行通信,通过IO ...
- 基于Java Web的传智播客crm企业管理系统的设计与实现
项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等.这里根据疫情当下,你 ...
- 人品测试器(Activity之间互传数据)
下面这个小程序是为了演示Activity之间怎么互传数据的,主要是intent里面的putExtra函数.基本数据的传输非常简单. package com.example.mytest;import ...
最新文章
- php request order,php.ini中的request_order推荐设置,requestorder_PHP教程
- 负载均衡算法-处理能力均衡
- oracle审计的格式
- 论文格式——合适【CSDN】发文
- application/x-www-form-urlencoded 与multipart/form-data
- 谈谈surging 微服务引擎 2.0的链路跟踪和其它新增功能
- 1800万元砸向子公司 点击网络巩固SaaS业务
- 汇编分析golang循环
- daily news新闻阅读客户端应用源码(兼容iPhone和iPad)
- Vue CLI 3 中文文档
- matlab gpu加速,Matlab之GPU加速方法
- linux输出替换字符串,Linux命令之sed-替换字符串
- 15个HTML5播放器插件
- neo4j springboot 日志_springBoot 与neo4j的简单整合示例
- js 获取输入的首字母拼音
- @Cacheable缓存注解使用
- 小米开发平台上架APP
- Java集合框架是什么?说出一些集合框架的优点?
- 共享打印机无法打印?常见的12种解决方法【详解】
- 18年大专毕业,转行入职车载测试岗位,薪资13K
热门文章
- /var/lib/docker/overlay2/xxxxx no such file or directory docker文件删除引发的问题
- 2022-2028中国曝光机市场现状及未来发展趋势
- GCC 在 Linux、Windows 系统安装
- 【C/S语言】.net平台
- Jupyter Magic - Timing(%%time %time %timeit)
- AI人工智能天机芯芯片
- CodeGen标记循环
- 无人驾驶传感器融合技术
- 高精地图中导航标识识别
- javaWeb——Servlet