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

JNA嵌套结构体,如何访问内嵌结构体的成员?

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

JNA嵌套结构体,如何访问内嵌结构体的成员?

如果不明白如何创建DLL动态链接库项目,可参照文章:https://blog.csdn.net/Xeon_CC/article/details/124873221

提出问题:
C语言程序有个结构体叫BaseGrid,里面有个Grid结构体的成员multi_grid,而且multi_grid是个二维指针数组,意思也就是说相当于java里面的Grid[][]二维数组类型。
请问,Java怎么访问C语言内的BaseGrid内的multi_grid成员变量,即Java如何访问嵌套结构体的成员变量?

在Java,我们会这么做:
BaseGrid baseGrid = new BaseGrid();
for循环,new很多个Grid对象,然后把Grid对象赋值给BaseGrid的multi_grid成员,其中multi_grid成员是装Grid对象的数组。
baseGrid.set(xxx); //做很多的set方法设置成员。
最后我们要访问baseGrid对象里面的multi_grid成员的某个元素Grid类的属性。
我们这么做:
baseGrid.getMultiGrid()[2][3].getW();
但是,如果是Java传递BaseGrid对象给C语言,然后返回baseGrid对象,这时候返回的baseGrid对象就不能如上所说的方法去获取了。
我们既然不能用getter方法获取,也不能用成员变量名称获取,比如obj.name,类似这种访问方式,思路是用地址偏移量的方式去访问成员。
获取成员的方法如下:

创建一个Maven项目,Java代码如下:

package com.example.jna_test01;

import com.sun.jna.*;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.HashMap;

@SpringBootApplication
public class JnaTest01Application {

    public interface CLibrary extends Library {
        JnaTest01Application.CLibrary INSTANCE = (JnaTest01Application.CLibrary) Native.load((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);

        void printf(String format, Object... args);
    }

    public interface DllForJava extends Library {
        DllForJava INSTANCE = (DllForJava) Native.load("src/main/java/com/example/jna_test01/dll/JNATestDLL.dll", DllForJava.class);

        public int getArrSum(Pointer arr, int row, int col);

        public BaseGrid getBaseGrid(BaseGrid.ByReference bg_ref, int row, int col);
    }

    //测试多重指针
    public void testMultiPointer() {
        CLibrary.INSTANCE.printf("Hello, Worldn");
        //分配一个24字节的内存,这里准备装入3个指针,一个指针占8个字节
        Pointer pointers = new Memory(24);
        int pointer_size = 8;
        int int_size = 4;
        int row = 3;
        int col = 5;
        for (int i = 0; i < row; i++) {
            //分配20字节的内存空间,并且该指针指向这个内存空间的首地址
            Pointer pointer = new Memory(20);
            for (int j = 0; j < col; j++) {
                pointer.setInt(j * int_size, i * j * 2 + 1);
            }
            pointers.setPointer(i * pointer_size, pointer);
            //这里不要释放内存
//            Native.free(Pointer.nativeValue(pointer));
        }
        //调用Dll动态链接库内的getArrSum函数
        System.out.println(DllForJava.INSTANCE.getArrSum(pointers, row, col));
        System.out.println("释放内存之前,pointers地址:" + pointers);
        Native.free(Pointer.nativeValue(pointers));
        Pointer.nativeValue(pointers, 0);
        System.out.println("释放内存之后,pointers地址:" + pointers);
    }

    //测试结构体里面有结构体成员
    public void testStructInStruct() {
        BaseGrid baseGrid = new BaseGrid();
        int row = 2;
        int col = 3;
        BaseGrid bg = DllForJava.INSTANCE.getBaseGrid(baseGrid, row, col);
        //https://blog.csdn.net/wankcn/article/details/121209323  C语言的long类型占用几个字节,看操作系统,只有64位的linux系统或者unix占8个字节
        //要注意,在c语言char* str是指针,无论你的char数组多长,只占8个字节,因为它只是一个指针
        HashMap fieldMap = new HashMap<>();
        fieldMap.put("w", 0);
        fieldMap.put("d", 4);
        fieldMap.put("db", 8);
        fieldMap.put("str", 16);
        fieldMap.put("lg", 24);
        //每个Grid对象占用几个字节,32个字节,计算是28个字节,但是由于8字节对齐,所以占用32个字节
        int gridSize = 32;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                int w = bg.multi_grid.getPointerArray(0, row)[i].getInt(j * gridSize + fieldMap.get("w"));
                int d = bg.multi_grid.getPointerArray(0, row)[i].getInt(j * gridSize + fieldMap.get("d"));
                double db = bg.multi_grid.getPointerArray(0, row)[i].getDouble(j * gridSize + fieldMap.get("db"));
                String str = byteArrToString(bg.multi_grid.getPointerArray(0, row)[i].getPointer(j * gridSize + fieldMap.get("str")).getByteArray(0, 20));
                int lg = bg.multi_grid.getPointerArray(0, row)[i].getInt(j * gridSize + fieldMap.get("lg"));
                System.out.println("w = " + w + ", d = " + d + ", db = " + db + ", " + str + ", " + "lg = " + lg);
            }
        }
    }

    public String byteArrToString(byte[] bytes) {
        String str = "";
        for (int i = 0; i < bytes.length; i++) {
            str += (char) bytes[i];
        }
        return str;
    }

    public static void main(String[] args) {
//        SpringApplication.run(DemoApplication.class, args);
        JnaTest01Application japp = new JnaTest01Application();
        japp.testMultiPointer();
        japp.testStructInStruct();
    }

}

package com.example.jna_test01;

import com.sun.jna.Pointer;
import com.sun.jna.Structure;

@Structure.FieldOrder({"multi_grid", "row", "col"})
public class BaseGrid extends Structure implements Structure.ByReference {

    public Pointer multi_grid;
    public int row;
    public int col;
}

package com.example.jna_test01;

import com.sun.jna.Structure;
import com.sun.jna.WString;

@Structure.FieldOrder({"w", "d"})
public class Grid extends Structure implements Structure.ByReference {
    public int w;
    public int d;
    public double db;
    public WString str;
    public long lg;
}

DLL动态链接库C语言代码:

#define EXPORT __declspec(dllexport)
#include 
#include 
using namespace std;

struct Grid {
	int w;
	int d;
	double db;
	char* str;
	long lg;
};

struct BaseGrid {
	Grid** multi_grid;
	int row;
	int col;
};



extern "C" {
	
	EXPORT int getArrSum(int** arr, int row, int col) {
		
		int sum = 0;
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				
				printf("%dt", arr[i][j]);
			}
			printf("n");
		}
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				sum += arr[i][j];
			}
		}
		return sum;
	}

	EXPORT BaseGrid* getBaseGrid(BaseGrid* baseGrid, int row, int col) {
		Grid** gridArrs = new Grid * [row];
		for (int i = 0; i < row; i++) {
			Grid* grids = new Grid[col];
			for (int j = 0; j < col; j++) {
				(grids + j)->w = i * j + 3;
				(grids + j)->d = i + j + i * j + 20;
				(grids + j)->db = i + j + i * j + 40;
				(grids + j)->str = new char[20]{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' };
				(grids + j)->lg = 90L;
			}
			gridArrs[i] = grids;
		}
		baseGrid->multi_grid = gridArrs;
		return baseGrid;
	}
}

执行结果

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

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

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