gpt4 book ai didi

java - 使用 SWIG 将字节数组转换为 C 结构

转载 作者:行者123 更新时间:2023-12-04 09:32:22 27 4
gpt4 key购买 nike

我在 C 中有以下结构:

typedef struct KFMutableBytes {
uint8_t * _Nullable bytes;
size_t length;
const size_t capacity;
} KFMutableBytes;
此结构作为指向函数的指针传递,如下所示:
KFMutableBytes bytes = ...;
someFunc(&bytes);
该函数写入 bytes.bytes高达 bytes.capacity ,并将写入的长度存储在 bytes.length 中.
到目前为止,我有这个:
%typemap(jni) KFMutableBytes * "jbyteArray"
%typemap(jtype) KFMutableBytes * "byte[]"
%typemap(jstype) KFMutableBytes * "byte[]"
%typemap(in) KFMutableBytes * {
KFMutableBytes *bytes = (KFBytes *)malloc(sizeof(KFMutableBytes));
if(bytes == NULL) {
jclass clazz = (*jenv)->FindClass(jenv, "java/lang/OutOfMemoryError");
(*jenv)->ThrowNew(jenv, clazz, "Not enough memory");
return $null;
}
KFMutableBytes b = KFMutableBytesCreate((uint8_t *) JCALL2(GetByteArrayElements, jenv, $input, 0), 0, (size_t) JCALL1(GetArrayLength, jenv, $input));
memcpy(bytes, &b, sizeof(b));
$1 = bytes;
}
%typemap(javain) KFMutableBytes * "$javainput"
/* Prevent default freearg typemap from being used */
%typemap(freearg) KFMutableBytes * {
JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1->bytes, 0);
free($1);
}
这意味着在 Java 中, someFuncsomeFunc(byte[] bytes) .问题是你不能得到写入的长度,并且字节数组长度不能在C中修改。所以我真的只需要映射 byte[]bytescapacity成员,并将长度成员映射到 long .但我不确定如何将字节数组映射到结构成员?

最佳答案

我已经解决了,但解决方案很复杂。本质上,我忽略了结构的属性,将我自己的构造函数和属性添加到 Java 中的类中,将结构的 Java 表示直接传递给 C,然后我在那里拉出 Java 属性来创建 C 结构,然后在函数是调用,将长度写回 java 对象并释放数组。

// ignore the properties of the struct to prevent them being added to the Java class
%ignore KFMutableBytes::bytes;
%ignore KFMutableBytes::capacity;
%ignore KFMutableBytes::length;
// Add our own constructors, properties and methods to the Java class
%extend KFMutableBytes {
#if defined(SWIG)
%proxycode %{
private byte[] bytes;
private int length;
public byte[] getBytes() {
if(length == 0) { return new byte[0]; }
return Arrays.copyOfRange(bytes, 0, length);
}
public KFMutableBytes(byte[] bytes) {
this.bytes = bytes;
length = 0;
}

public KFMutableBytes(int capacity) {
this.bytes = new byte[capacity];
length = 0;
}
%}
#endif
}
// Tell SWIG to pass the java object straight to C
%typemap(jni) KFMutableBytes * "jobject"
%typemap(jtype) KFMutableBytes * "KFMutableBytes"
%typemap(jstype) KFMutableBytes * "KFMutableBytes"
// In C, get the added properties from the Java object and set those to our struct
%typemap(in) KFMutableBytes * {
jclass clazz = JCALL1(FindClass, jenv, "com/example/myapplication/cppinterface/KFMutableBytes");
jfieldID fid = JCALL3(GetFieldID, jenv, clazz, "bytes", "[B");
jobject byteArrayObj = JCALL2(GetObjectField, jenv, $input, fid);
jbyteArray byteArray = *(jbyteArray *)&byteArrayObj;
jfieldID fid2 = JCALL3(GetFieldID, jenv, clazz, "length", "I");
int length = JCALL2(GetIntField, jenv, $input, fid2);

KFMutableBytes *bytes = (KFBytes *)malloc(sizeof(KFMutableBytes));
if(bytes == NULL) {
jclass clazz = (*jenv)->FindClass(jenv, "java/lang/OutOfMemoryError");
(*jenv)->ThrowNew(jenv, clazz, "Not enough memory");
return $null;
}
// Because ->capacity is const, we can't set it directly, we have to create another struct and copy to our allocated struct
KFMutableBytes b = KFMutableBytesCreate((uint8_t *) JCALL2(GetByteArrayElements, jenv, byteArray, 0), length, (size_t) JCALL1(GetArrayLength, jenv, byteArray));
memcpy(bytes, &b, sizeof(b));
$1 = bytes;
}
%typemap(javain) KFMutableBytes * "$javainput"
// When finished with the struct, set the length back to the object and release the byte array before freeing
%typemap(freearg) KFMutableBytes * {
jclass clazz = JCALL1(FindClass, jenv, "com/example/myapplication/cppinterface/KFMutableBytes");
jfieldID fid = JCALL3(GetFieldID, jenv, clazz, "bytes", "[B");
jobject byteArrayObj = JCALL2(GetObjectField, jenv, $input, fid);
jbyteArray byteArray = *(jbyteArray *)&byteArrayObj;
jfieldID fid2 = JCALL3(GetFieldID, jenv, clazz, "length", "I");
JCALL3(SetIntField, jenv, $input, fid2, (int)$1->length);
JCALL3(ReleaseByteArrayElements, jenv, byteArray, (jbyte *) $1->bytes, 0);

free($1);
}

关于java - 使用 SWIG 将字节数组转换为 C 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62778840/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com