栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JNA参数类型转换(含接收、发送结构体)——JNA-JNI(五)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 
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 // __cplusplus

EXPORT  void xmltest(Student s);
EXPORT  Location struc(Location l);

#endif // SIMPLE_H_INCLUDED
#include 
#include 
#include 
#include 
#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;//定义结构体类型变量s1
    s1.longitude = 1;//结构体变量的引用
    s1.latitude = 2;
    const char *s = "nowloc";
    s1.info = (char*)s;
    s1.column = &s;

    return s1;
}
JNA调用 编写结构体

在Java端复写结构体,在复写的时候需要注意两点:

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

    @Override
    protected 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{}
    
    @Override
    protected List 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
原因:数据类型不对应

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782064.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号