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部分

  1. 一个分别发送和接收,都使用结构体
  2. 另一个只发送结构体,无返回值

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端复写结构体,在复写的时候需要注意两点:

  1. 需要在结构体定义中定义2个内部类ByReference和ByValue,来实现指针类型接口和值类型接口
  2. 重写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

  1. 只要涉及到结构体的传递,必须使用ByReference或者ByValue中的一种
  2. 指针和引用的传递使用ByReference
  3. 拷贝参数传递使用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(五)相关推荐

  1. linux socket 结构定义 send,Linux下Socket编程中用send发送结构体

    Linux网络通信 Linux下多客户端聊天软件 最近在开发一个Linux下的聊天软件,好久没有做C语言的开发了,感觉到很多东西已经生疏了,这下又碰到用Socket传递结构体的问题,google了一下 ...

  2. c语言send发送结构体,Socket编程中用send发送结构体

    Socket编程中用send发送结构体 原创 2010年04月28日 19:17:00 标签:socket /编程 /struct /google /string /input 11868 最近在开发 ...

  3. Linux下Socket编程中用send发送结构体

    转自:http://tech.ddvip.com/2008-10/122543769687623.html Linux网络通信 Linux下多客户端聊天软件 Linux程序设计 Linux socke ...

  4. c语言发送结构体 文件

    Linux C Socket编程发送结构体.文件详解及实例 利用Socket发送文件.结构体.数字等,是在Socket编程中经常需要用到的.由于Socket只能发送字符串,所以可以使用发送字符串的方式 ...

  5. 关于VC网络编程中用 char 发送结构体的说明

    关于VC网络编程中用 char 发送结构体的说明     在VC中要发送struct的程序,如果需要中间打包的话,首先因该将结构体转换为字节型的.然后再用 send (SOCKET s,const c ...

  6. 内核中用于数据接收的结构体struct msghdr

    我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,ping另一台主机172.16.48.1.我们使用系统调用send ...

  7. 内核中用于数据接收的结构体struct msghdr以及iovec介绍

    我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,ping另一台主机172.16.48.1.我们使用系统调用send ...

  8. stm32串口发送数据的配置,以及通过串口发送结构体数组总是多一个00字节的问题

    最近用stm32编写串口发送程序,在硬件方面需要做如下准备: 1.stm32开发板,这里我的是stm32f030f4p4开发板,单片机的串口发送的引脚为PA9-TX,PA10-RX. 2.为了调试串口 ...

  9. Java中发送结构体

    http://blog.csdn.net/xwchen/article/details/1585908 最近给个朋友做个网站的客户端,使用C/S模式,Client为VC6开发,Server为Java, ...

最新文章

  1. MAC使用homeBrew安装Redis
  2. bzoj 2257[Jsoi2009]瓶子和燃料 数论/裴蜀定理
  3. MySQL中实现连续日期内数据统计,缺省天数0补全
  4. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之集群概念介绍(一)
  5. Adopt Open JDK官方文档(四)基于虚拟机的编译环境
  6. 牛客网模拟笔试——膨胀的牛牛(JavaScript)
  7. 日常见到一些命令使用实例~(持续更新!)
  8. Labelimg图像标注
  9. Mac 上 QuickTime Player 播放器以 1.1、1.2 倍速等更精确速度快进/快退播放的方法
  10. 浅谈国内软件信息化项目项目立项管理办法
  11. 使用支付宝小程序input组件的坑
  12. 【细胞分割】基于形态学算法实现红细胞计数matlab源码含 GUI
  13. 圆排列公式推导_【圆面积公式计算】圆形面积计算公式
  14. java 调用 yed 绘制 流程图_让人一见倾心的流程图绘制软件yEd
  15. 获取android应用缓存目录时遇到的问题
  16. idea+springmvc+spring+mybatis+maven整合返回json数据web api-
  17. 北京大学MOOC 程序设计与算法(三)魔兽世界三(开战)
  18. 基于STM32的Flash擦除方式
  19. windows修复命令
  20. java 删除文件失败_java中File的delete()方法删除文件失败的原因

热门文章

  1. EasyX中使用背景音乐
  2. !important
  3. 大数据发展前景:大数据未来竟是这样?
  4. 【VBA研究】打印银行对账单(套打)
  5. 龙渊服务器信息丢失,巨龙之战龙渊旧,龙渊号怎么没有31服务器
  6. AutoCAD VBA简单文字操作
  7. win10增加matlab虚拟内存,增加虚拟内存,详细教您win10增加虚拟内存的方法
  8. 惊艳于红警开源代码?赏心悦目的代码注释,我们也可以 !
  9. Python实现VRP常见求解算法——差分进化算法(DE)
  10. mysql的主句与从句_主句、从句、复合句