如何将SWIGTYPE_p重命名为更友好的东西?

时间:2013-04-19 14:29:33

标签: java c++ swig

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

uint8_t* getData();

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

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

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

1 个答案:

答案 0 :(得分:1)

在一般情况下,您可以rename SWIGTYPE_p_... using an empty definition将其包装为不透明的“句柄”。

这个特定的实例看起来像你有一个标准的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. 更严重的是,它会干扰您在同一界面中拥有的任何其他阵列,甚至可能会干扰字符串处理
  3. 更好的解决方案可能是使用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,并且采用getitemsetitem方法。

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

    如果您知道先验数组的大小,您可以采取步骤将其包装为Java中的有界而非无界数组,例如: by implementing AbstractList