JNA(十)结构体中字符串数组

本文介绍了如何在C语言和Java中通过结构体处理字符串数组,包括C代码中的动态内存分配和释放,以及Java中使用JNA进行跨语言通信。展示了如何通过`ByValue`方式传递对象给动态库并清理内存。

前言

关于环境和dll的生成,不懂的同学可以去查看JNA(一)与JNA(二)的内容
结构体可能比较重要,大多数Java应用与共享库的交互基本是以结构体做为桥梁,这里是结构体中包含string数组的情形

操作

1.C语言代码

头文件(library.h)

#ifndef CDYNAMICDEMO_LIBRARY_H
#define CDYNAMICDEMO_LIBRARY_H

#include <string.h>
#include <stdlib.h>

// 字符串数组结构体
typedef struct Teacher {
    // 别名
    char **alias;
    // 别名数量
    int num;
} Teacher;

void setTeacher(Teacher *teacher);

struct Teacher getTeacher();

void clearTeacher(Teacher teacher);

#endif //CDYNAMICDEMO_LIBRARY_H

代码文件(library.c)

#include "library.h"
#include <stdio.h>

void setTeacher(Teacher *teacher) {
    int i = 0;
    printf("\nalias count: %d", teacher->num);
    for (; i < teacher->num; i++) {
        printf("\nteacher's alia name%d: %s", i, teacher->alias[i]);
    }
}

struct Teacher getTeacher() {
    Teacher teacher;
    teacher.num = 4;
    teacher.alias = malloc(sizeof(char *) * teacher.num);
    teacher.alias[0] = malloc(sizeof(char) * 4);
    strcpy(teacher.alias[0], "abc");

    teacher.alias[1] = malloc(sizeof(char) * 5);
    strcpy(teacher.alias[1], "abcd");

    teacher.alias[2] = malloc(sizeof(char) * 6);
    strcpy(teacher.alias[2], "abcde");

    teacher.alias[3] = malloc(sizeof(char) * 13);
    strcpy(teacher.alias[3], "abcdef中文");

    return teacher;
}

void clearTeacher(Teacher teacher) {
    printf("\n释放teacher所申请的内存");
    int num = teacher.num;
    for (int i = 0; i < num; i++) {
        free(teacher.alias[i]);
    }
    free(teacher.alias);
}

2.java代码

package com.dynamic.demo.struct;

import com.sun.jna.*;
import com.sun.jna.platform.linux.LibC;
import com.sun.jna.ptr.PointerByReference;
import lombok.Getter;
import lombok.Setter;

import java.util.Arrays;
import java.util.List;

public interface StructStringArrayLibrary extends Library {
    StructStringArrayLibrary INSTANCE = Native.load(Platform.isWindows() ? "libCDynamicDemo" : "", StructStringArrayLibrary.class);

    void setTeacher(Structure.ByReference reference);

    Teacher.ByValue getTeacher();

    void clearTeacher(Teacher.ByValue teacher);

    @Getter
    @Setter
    static class Teacher extends Structure {
        public static class ByReference extends Teacher implements Structure.ByReference {
        }

        public static class ByValue extends Teacher implements Structure.ByValue {
        }

        // char**
        public Pointer alias;
        public int num;

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("alias", "num");
        }
    }

    public static void main(String[] args) {
        int num = 5;
        String alias[] = new String[num];
        alias[0] = "zhansan";
        alias[1] = "lisi";
        alias[2] = "wangwu";
        alias[3] = "zhaoliu";
        alias[4] = "钱七";

        Teacher.ByReference teacher = new Teacher.ByReference();
        teacher.setNum(num);
        teacher.setAlias(new StringArray(alias));

        StructStringArrayLibrary.INSTANCE.setTeacher(teacher);

        // 获取字符串数组
        Teacher.ByValue teacher1 = StructStringArrayLibrary.INSTANCE.getTeacher();
        System.out.println("别名数量: " + teacher1.getNum());
        Pointer alias1 = teacher1.getAlias();
        String[] stringArray = alias1.getStringArray(0, teacher1.getNum());
        for (String name : stringArray) {
            System.out.println(name);
        }

        //清理
        StructStringArrayLibrary.INSTANCE.clearTeacher(teacher1);
    }
}

3.查看输出

在这里插入图片描述

总结

  1. 仔细观察,也可以通过ByValue的方式直接传对象到动态库中,而无需通过引用
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值