gpt4 book ai didi

包装无符号二进制数据的 SWIG 技术

转载 作者:行者123 更新时间:2023-12-04 12:11:41 25 4
gpt4 key购买 nike

我有一个 C 函数,它返回一个表示二进制数据的 unsigned char*。我在文档中注意到 SWIG 有一个很好的类型映射来处理二进制数据作为 C 函数的输入,但是当 C 函数返回二进制数据及其无符号数据时呢?有任何想法吗?

swig.i:

%apply (char *STRING, size_t LENGTH) { (const char data[], size_t len) }
%inline %{
void binaryChar1(const char data[], size_t len) {
printf("len: %d data: ", len);
for (size_t i=0; i<len; ++i)
printf("%x ", data[i]);
printf("\n");
}
%}

java :
byte[] data = "hi\0jk".getBytes();
example.binaryChar1(data);

C 示例:
 enw_resultrow_t *result_row = getResultRow();
unsigned char *blob;
while ((blob = getBinaryFromRow(result_row, &length))) {
char fname[32];
FILE *fp;
i++;
snprintf (fname, sizeof(fname), "FileXYZ", i);
printf ("Blob from %d:%s is saved in %s has %d bytes\n", i,
aSender?inet_ntoa(aSender->sin_addr):"???", fname, length);
if ((fp = fopen (fname, "w"))) {
l = fwrite (blob, sizeof (unsigned char), length, fp);
printf("Successfully wrote %d bytes to file\n", l);
fclose (fp);
} else {
printf("Error writing file");
}
}

最佳答案

我创建了一个测试用例来反射(reflect)你正在尝试做的事情(我认为):

#include <stdlib.h>

enum thing {
ONE=1,
TWO=2,
THREE=3
};

static signed char *get_data(enum thing t, size_t *len) {
*len = (size_t)t;
signed char *ret = malloc(sizeof(signed char) * (*len));
for (size_t i = 0; i < *len; ++i) {
ret[i] = i;
}
return ret;
}

包装 get_data()我使用了以下界面:
%module test

%{
#include "test.h"
%}

%typemap(jni) signed char *get_data "jbyteArray"
%typemap(jtype) signed char *get_data "byte[]"
%typemap(jstype) signed char *get_data "byte[]"
%typemap(javaout) signed char *get_data {
return $jnicall;
}

%typemap(in,numinputs=0,noblock=1) size_t *len {
size_t length=0;
$1 = &length;
}

%typemap(out) signed char *get_data {
$result = JCALL1(NewByteArray, jenv, length);
JCALL4(SetByteArrayRegion, jenv, $result, 0, length, $1);
}

%include "test.h"

基本上这样做是从 get_data 设置返回类型函数从 JNI 代码一直到 SWIG 代理都是一个 Java 数组。完成后,它会设置一个临时 size_tlength这将用于调用真正的 C 函数并存储结果。 (在我看到 this answer to another question 之前我没有看到 noblock ,它告诉 SWIG 不要让 typemap 参数独立,因此意味着给定函数只能有一个 size_t *len 参数,看看是什么如果您很好奇,它会对生成的包装器代码起作用)。

一旦设置好,剩下的就是使用 JNI 调用分配一个数组并将一些值复制到其中。

我测试了这个:
public class run {
public static void main(String[] argv) {
System.loadLibrary("test");
byte[] test1 = test.get_data(thing.ONE);
System.out.println(test1.length);
System.out.println(test1 + ": " + test1[0]);

byte[] test2 = test.get_data(thing.TWO);
System.out.println(test2.length);
System.out.println(test2 + ": " + test2[0] + ", " + test2[1]);

byte[] test3 = test.get_data(thing.THREE);
System.out.println(test3.length);
System.out.println(test3 + ": " + test3[0] + ", " + test3[1] + ", " + test3[2]);

}
}

然后给出:

1
[B@525483cd:0
2
[B@2a9931f5: 0, 1
3
[B@2f9ee1ac: 0, 1, 2

我通过让我的成为 signed char 来稍微作弊.如果你想让它无符号,你要么需要使用强制转换(最好注意符号丢失)或 short/ int通过适当的转换。

小心处理真实代码中的内存所有权。

关于包装无符号二进制数据的 SWIG 技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9934059/

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