JNA参数类型转换(含接收、发送结构体)——JNA-JNI(五)
JNA参数类型转换(含接收、发送结构体)——JNA-JNI(五)
系列文章:
Java通过JNI调用C++动态链接库dll,并打在jar包内 ——JNA-JNI(一)
Java使用JNA调用C++动态链接库——JNA-JNI(二)
Mac M1 Xcode创建动态链接库dylib(c++)——JNA-JNI(三)
JNA调用dll(c++)附带解析xml——JNA-JNI(四)
JNA参数类型转换(含接收、发送结构体)——JNA-JNI(五)
本文目录
- JNA参数类型转换(含接收、发送结构体)——JNA-JNI(五)
- 官网映射关系查看
- c++结构体
- JNA调用
- 编写结构体
- 声明函数
- 调用
- 运行结果
- 可能报错
官网映射关系查看
https://java-native-access.github.io/jna/5.5.0/javadoc/
实现两个例子,java部分
- 一个分别发送和接收,都使用结构体
- 另一个只发送结构体,无返回值
c++结构体
#ifndef SIMPLE_H_INCLUDED
#define SIMPLE_H_INCLUDED#include <string>
using namespace std;/*声明只发结构体*/
typedef struct Student
{int Gender;char *Mobile;int Email;void *column;
};/*声明收发结构体*/
typedef struct Location
{int longitude;int latitude;char *info;void *column;
};#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif // __cplusplusEXPORT void xmltest(Student s);
EXPORT Location struc(Location l);#endif // SIMPLE_H_INCLUDED
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include "xxx.h"using namespace std;void xmltest(Student s) {cout << s.Gender << endl;cout << s.Mobile << endl;cout << s.Email << endl;cout << s.column << endl;
}Location struc(Location l) {cout << l.longitude << endl;cout << l.latitude << endl;cout << l.info << endl;cout << l.column << endl;struct Location s1;//定义结构体类型变量s1s1.longitude = 1;//结构体变量的引用s1.latitude = 2;const char *s = "nowloc";s1.info = (char*)s;s1.column = &s;return s1;
}
JNA调用
编写结构体
在Java端复写结构体,在复写的时候需要注意两点:
- 需要在结构体定义中定义2个内部类ByReference和ByValue,来实现指针类型接口和值类型接口
- 重写getFieldOrder()来告诉C/C++的成员取值次序,结构体定义取值次序,需要与c++中对齐,不然报NoSuchFieldError错误!
收发
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.List;public class Location extends Structure {public static class ByReference extends Location implements Structure.ByReference{ }public static class ByValue extends Location implements Structure.ByValue{ }public int longitude;public int latitude;public String info;public Pointer column;@Overrideprotected List getFieldOrder() {return Arrays.asList(new String[]{"longitude", "latitude", "info", "column"});}
}
只发不收
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import java.util.Arrays;
import java.util.List;public class QueryStructure extends Structure {public int Gender;public String Mobile;public int Email;public Pointer column;/*内部类实现指针类型接口*/public static class ByReference extends QueryStructure implements Structure.ByReference{}/*内部类实现值类型接口*/public static class ByValue extends QueryStructure implements Structure.ByValue{}/*** 定义取值次序,需要与c++中对齐,不然报NoSuchFieldError* @return*/@Overrideprotected List<String> getFieldOrder() {return Arrays.asList(new String[] {"Gender", "Mobile", "Email", "column"});}
}
关于ByReference和ByValue
- 只要涉及到结构体的传递,必须使用ByReference或者ByValue中的一种
- 指针和引用的传递使用ByReference
- 拷贝参数传递使用ByValue
声明函数
区别主要在声明处,如果收发的话,使用ByValue,只发不接收使用ByReference,否则会报错Exception in thread "main" java.lang.Error: Invalid memory access
public interface CLibrary extends Library {DemoApplication.CLibrary INSTANCE = (DemoApplication.CLibrary) Native.loadLibrary("Project6", DemoApplication.CLibrary.class); // 引入库文件public void xmltest(QueryStructure.ByReference queryInfo);public Location.ByValue struc(Location.ByValue l);
}
调用
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class);//QueryStructure.ByReference qs = new QueryStructure.ByReference();qs.Gender = 1;qs.Mobile = "222";qs.Email = 3;qs.column = Pointer.createConstant(2431128);DemoApplication.CLibrary.INSTANCE.xmltest(qs);//Location.ByValue ins = new Location.ByValue();ins.latitude = 3;ins.longitude = 4;ins.info = "oldloc";ins.column = Pointer.createConstant(2431128);Location.ByValue res = CLibrary.INSTANCE.struc(ins);System.out.println(res.latitude);System.out.println(res.longitude);System.out.println(res.info);System.out.println(res.column);}}
运行结果
只发不收的结果
收发结果
可能报错
Exception in thread “main” java.lang.Error: Invalid memory access
原因:数据类型不对应
JNA参数类型转换(含接收、发送结构体)——JNA-JNI(五)相关推荐
- linux socket 结构定义 send,Linux下Socket编程中用send发送结构体
Linux网络通信 Linux下多客户端聊天软件 最近在开发一个Linux下的聊天软件,好久没有做C语言的开发了,感觉到很多东西已经生疏了,这下又碰到用Socket传递结构体的问题,google了一下 ...
- c语言send发送结构体,Socket编程中用send发送结构体
Socket编程中用send发送结构体 原创 2010年04月28日 19:17:00 标签:socket /编程 /struct /google /string /input 11868 最近在开发 ...
- Linux下Socket编程中用send发送结构体
转自:http://tech.ddvip.com/2008-10/122543769687623.html Linux网络通信 Linux下多客户端聊天软件 Linux程序设计 Linux socke ...
- c语言发送结构体 文件
Linux C Socket编程发送结构体.文件详解及实例 利用Socket发送文件.结构体.数字等,是在Socket编程中经常需要用到的.由于Socket只能发送字符串,所以可以使用发送字符串的方式 ...
- 关于VC网络编程中用 char 发送结构体的说明
关于VC网络编程中用 char 发送结构体的说明 在VC中要发送struct的程序,如果需要中间打包的话,首先因该将结构体转换为字节型的.然后再用 send (SOCKET s,const c ...
- 内核中用于数据接收的结构体struct msghdr
我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,ping另一台主机172.16.48.1.我们使用系统调用send ...
- 内核中用于数据接收的结构体struct msghdr以及iovec介绍
我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,ping另一台主机172.16.48.1.我们使用系统调用send ...
- stm32串口发送数据的配置,以及通过串口发送结构体数组总是多一个00字节的问题
最近用stm32编写串口发送程序,在硬件方面需要做如下准备: 1.stm32开发板,这里我的是stm32f030f4p4开发板,单片机的串口发送的引脚为PA9-TX,PA10-RX. 2.为了调试串口 ...
- Java中发送结构体
http://blog.csdn.net/xwchen/article/details/1585908 最近给个朋友做个网站的客户端,使用C/S模式,Client为VC6开发,Server为Java, ...
最新文章
- MAC使用homeBrew安装Redis
- bzoj 2257[Jsoi2009]瓶子和燃料 数论/裴蜀定理
- MySQL中实现连续日期内数据统计,缺省天数0补全
- 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)
- Adopt Open JDK官方文档(四)基于虚拟机的编译环境
- 牛客网模拟笔试——膨胀的牛牛(JavaScript)
- 日常见到一些命令使用实例~(持续更新!)
- Labelimg图像标注
- Mac 上 QuickTime Player 播放器以 1.1、1.2 倍速等更精确速度快进/快退播放的方法
- 浅谈国内软件信息化项目项目立项管理办法
- 使用支付宝小程序input组件的坑
- 【细胞分割】基于形态学算法实现红细胞计数matlab源码含 GUI
- 圆排列公式推导_【圆面积公式计算】圆形面积计算公式
- java 调用 yed 绘制 流程图_让人一见倾心的流程图绘制软件yEd
- 获取android应用缓存目录时遇到的问题
- idea+springmvc+spring+mybatis+maven整合返回json数据web api-
- 北京大学MOOC 程序设计与算法(三)魔兽世界三(开战)
- 基于STM32的Flash擦除方式
- windows修复命令
- java 删除文件失败_java中File的delete()方法删除文件失败的原因