gpt4 book ai didi

java - 在 Java 中使用 SWIG 处理返回指向结构数组的指针的 C 函数

转载 作者:行者123 更新时间:2023-11-30 04:55:59 24 4
gpt4 key购买 nike

我试图找出需要进行哪些 SWIG 接口(interface)文件更改才能处理 getFoo 返回指向自定义结构数组 (sender_id_t) 的指针。没有任何特殊的 SWIG 接口(interface)代码,我只得到 Java 端的指针。如何将该指针转换为可以循环或迭代的对象(在 Java 中),以便获取每个 sender_id_t id 值?感谢任何建议。

C 结构:

typedef unsigned char id_v1_t[32];
typedef id_v1_t id_t;
%rename (Sample) sender_id_t_;
struct sender_id_t_ {
id_t id;
uint32_t phy_idx;
};

C 函数:

//This will return a pointer to an array of sender_id_t data.  The number of elements is retrieved from a separate call. 
sender_id_t* getFoo(resultset_t* resultset);

异常(exception):

 [exec] test_wrap.c: In function `new_foo_array':
[exec] test_wrap.c:785: error: invalid application of `sizeof' to incomplete type `sender_id_t_'
[exec] test_wrap.c: At top level:
[exec] test_wrap.c:792: error: return type is an incomplete type
[exec] test_wrap.c: In function `foo_array_getitem':
[exec] test_wrap.c:793: error: invalid use of undefined type `struct sender_id_t_'
[exec] test_wrap.c:793: error: dereferencing pointer to incomplete type
[exec] test_wrap.c:793: warning: `return' with a value, in function returning void
[exec] test_wrap.c: At top level:
[exec] test_wrap.c:795: error: parameter `value' has incomplete type
[exec] test_wrap.c: In function `foo_array_setitem':

最佳答案

最简单的解决方案根本不涉及编写任何 JNI - 实际上它是 method 2 。因此,我所做的就是使用 carrays.i 公开一个非常基本的接口(interface),然后编写一点 Java 使其公共(public) View 更加可用/直观。关键是您需要提供一种将数组知识和数组长度结合在一起的方法。我整理了一个最小的完整示例来说明,它返回一个 Java 数组,但它同样适用于 ArrayList 或您喜欢的任何集合。

首先是一个头文件,带有紧凑的内联实现:

#ifndef TEST_H
#define TEST_H

struct Foo {
int v;
};

inline static struct Foo *getFoo() {
static struct Foo r[] = {{0},{1},{2}};
return r;
}

inline static unsigned short numFoo() {
return 3;
}

#endif

然后将其包裹起来:

%module test

%{
#include "test.h"
%}

%include <carrays.i>
%array_functions(struct Foo, foo_array);

%rename(getFooImpl) getFoo;
%javamethodmodifiers getFoo() "private";
%javamethodmodifiers numFoo() "private";
%include "test.h"

%pragma(java) modulecode=%{
public static Foo[] getFoo() {
final int num = numFoo();
Foo ret[] = new Foo[num];
Foo result = getFooImpl();
for (int i = 0; i < num; ++i) {
ret[i] = foo_array_getitem(result, i);
}
return ret;
}
%}

我们将头文件中的getFoo()重命名,并使其与相应的numFoo() private,即实现细节.

使用这两个私有(private)函数,我们可以编写一个真正的 public Foo[] getFoo(),它调用这两个函数,然后将结果复制到已知大小的实际数组中。

我对此进行了测试:

public class main {
public static void main(String[] argv) {
System.loadLibrary("test");
Foo[] foos = test.getFoo();
System.out.println(foos[2].getV());
}
}

在我看来,这个解决方案比相应的基于 JNI 的示例更干净 - 编写起来更简单,并且更难引入错误,这使得它更易于维护。任何查看它的 Java C 程序员几乎都能明白发生了什么。就性能而言,它可能不会差太多,并且在某些关键路径上可能不会花费大量时间 - 如果基准测试显示这是一个问题,那么以后仍然很容易走上 JNI 道路。

为了“使其私有(private)”方面的完整性,您可能还需要执行以下操作:

%javamethodmodifiers foo_array_getitem "private";
%ignore foo_array_setitem;
%ignore delete_foo_array;
%ignore new_foo_array;
%include <carrays.i>
%array_functions(struct Foo, foo_array);

隐藏由 %array_functions 宏生成的所有函数。

关于java - 在 Java 中使用 SWIG 处理返回指向结构数组的指针的 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8524871/

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