0

我有一个 c++ 函数返回一个 uint8_t* 数组,如:

uint8_t* getData();

Swig 将其映射到 SWIGTYPE_p_unsigned_char。我想要一个更友好的名字。在我的 .i 文件中,我只是简单地包含了包含上述代码的 h 文件。我试过 %rename 但它不起作用:

%rename (SWIGTYPE_p_unsigned_char) u8_t;
%include "myhfile.h"

如何强制 Swig 重命名我的类型(或以其他方式解决)?

4

1 回答 1

1

在一般情况下,您可以使用空定义重命名SWIGTYPE_p_...以将其包装为不透明的“句柄”。

这个特定的实例看起来像你有一个标准的 typedef。您仍然可以按照链接的答案进行操作,例如:

%module test

%{
#include <stdint.h>
%}

typedef struct {
} uint8_t;

%inline %{
  uint8_t *getData() {
    static uint8_t d[5];
    return d;
  }
%}

它丢失了 SWIGTYPE_ 前缀,可以用作:

public class run {
  public static void main(String[] argv) {
    System.loadLibrary("test");
    test.getData();
  }
}

然而这并不理想:

  1. 无法访问返回的数组(您可能希望在 Java 中访问该数据,而不仅仅是传递它)
  2. 更严重的是,它会干扰您在同一界面中拥有的任何其他数组,甚至可能干扰字符串处理

更好的解决方案可能是使用 SWIG carrays.i 接口来包装它并使用无界数组类来精确复制您在 C++ 中的行为:

%module test

%{
#include <stdint.h>
%}

%include <stdint.i>
%include <carrays.i>

%array_class(uint8_t, U8_Array);

%typemap(jstype) uint8_t *getData "U8_Array"
%typemap(javaout) uint8_t *getData {
  return new $typemap(jstype,uint8_t *getData)($jnicall,$owner);
}

%inline %{
  uint8_t *getData() {
    static uint8_t d[5];
    return d;
  }
%}

你的返回类型现在将来自carrays.i并且有一个getitemandsetitem方法。

实际上,您可以使用jstypeandjavaout类型映射将结果(转换为 a 的指针long)映射到任何Java 类型,它不必来自 carrays.i ,这恰好是一个非常有用的案例。或者,如果您愿意,也可以编写 JNI 代码,直接将其作为 Java 数组返回。

如果您先验地知道数组的大小,则可以采取措施将其包装为 Java 中的有界而不是无界数组,例如通过实现AbstractList.

于 2013-04-28T13:24:47.173 回答