前言
关于环境和dll的生成,不懂的同学可以去查看JNA(一)与JNA(二)的内容
后续的内容都是以set和get进行:
所谓set,就是往动态库中发送;而get就是从动态库中获取
操作
1.C语言代码
头文件(library.h)
#ifndef CDYNAMICDEMO_LIBRARY_H
#define CDYNAMICDEMO_LIBRARY_H
#include <string.h>
#include <stdlib.h>
// 字符串数组一
void setStringArr(const char **arr, int len);
void getStringArr(char ***strings, int *len);
void cleanStringArr(char **strings, int len);
#endif //CDYNAMICDEMO_LIBRARY_H
代码文件(library.c)
#include "library.h"
#include <stdio.h>
void setStringArr(const char **arr, int len) {
printf("\n数组长度: %d", len);
for (int i = 0; i < len; i++) {
printf("\n%d: %s", i, arr[i]);
}
}
void getStringArr(char ***strings, int *len) {
*len = 3;
printf("\nsizeof(char *) = %ld", sizeof(char *));
*strings = (char **) malloc(sizeof(char *) * *len);
memset(*strings, 0, sizeof(char *) * *len);
// 中括号的优先级比指针大
(*strings)[0] = malloc(sizeof(char) * 4);
strcpy((*strings)[0], "111");
(*strings)[1] = malloc(sizeof(char) * 5);
strcpy((*strings)[1], "1112");
(*strings)[2] = malloc(sizeof(char) * 10);
strcpy((*strings)[2], "123456789");
}
void cleanStringArr(char **strings, int len) {
for (int i = 0; i < len; i++) {
free(strings[i]);
}
free(strings);
printf("\n字符串数组清理完成!");
}
2.java代码
package com.dynamic.demo.strings;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
public interface StringArrayLibrary extends Library {
StringArrayLibrary INSTANCE = Native.load(Platform.isWindows() ? "libCDynamicDemo" : "", StringArrayLibrary.class);
void setStringArr(String[] arr, int len);
void getStringArr(PointerByReference reference, IntByReference lenReference);
void cleanStringArr(Pointer pointer, int len);
public static void main(String... args) {
long currentTimeMillis = System.currentTimeMillis();
StringArrayLibrary.INSTANCE.setStringArr(new String[]{"abc", "123"}, 2);
PointerByReference strings = new PointerByReference();
IntByReference len = new IntByReference();
StringArrayLibrary.INSTANCE.getStringArr(strings, len);
System.out.println("长度: " + len.getValue());
Pointer pointer = strings.getValue();
String[] stringArray = pointer.getStringArray(0, len.getValue());
for (String text : stringArray) {
System.out.println(text);
}
StringArrayLibrary.INSTANCE.cleanStringArr(pointer, len.getValue());
System.out.println("耗时: " + (System.currentTimeMillis() - currentTimeMillis) + "ms");
}
}
3.查看输出
4.代码比较
总结
- 传入数组是一个引用,所以同时还要告诉C数组的长度
- 同样的,因为传过来的是引用,所以java中取字符串数组也需要知道长度
- 这种玩法性能不是很好,更好的写法参考:JNA(六)字符串操作三
- 至于为什么C语言中这么多星号的指针,本人也不是特别清楚(只能勉强看懂),另外注意java中的写法