如何在Java中使用SWIG Generated C结构作为通过SWIG / JNI输入C函数

时间:2011-11-22 23:19:31

标签: java java-native-interface swig

我有一个SWIG接口文件,它将一些C函数(通过JNI)公开给我的Java应用程序,这些C结构用作C函数的输入(通过SWIG / JNI)。 SWIG将结构生成为Java类,但我不确定如何设置结构属性,因为setter采用SWIG生成的类型。我需要在将结构属性作为输入传递到我的Java类的C函数之前设置它们。 example_location_id_t_是我需要传递的类,但IdPhy_idx的setter采用以下SWIG类型。如何填充SWIGTYPE_p_unsigned_charSWIGTYPE_p_uint32_t,以便我可以设置Id类的Phy_idxSWIGTYPE_p_uint32_t属性?

setId(SWIGTYPE_p_unsigned_char value)setPhy_idx(SWIGTYPE_p_uint32_t value)

package com.test.jni;

public class SWIGTYPE_p_unsigned_char {
  private long swigCPtr;

  protected SWIGTYPE_p_unsigned_char(long cPtr, boolean futureUse) {
    swigCPtr = cPtr;
  }

  protected SWIGTYPE_p_unsigned_char() {
    swigCPtr = 0;
  }

  protected static long getCPtr(SWIGTYPE_p_unsigned_char obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }
}


package com.test.jni;

public class SWIGTYPE_p_uint32_t {
  private long swigCPtr;

  protected SWIGTYPE_p_uint32_t(long cPtr, boolean futureUse) {
    swigCPtr = cPtr;
  }

  protected SWIGTYPE_p_uint32_t() {
    swigCPtr = 0;
  }

  protected static long getCPtr(SWIGTYPE_p_uint32_t obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }
}

package com.test.jni;

public class example_location_id_t_ {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  public example_location_id_t_ (long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  public static long getCPtr(example_location_id_t_ obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        ExampleJNI.delete_example_location_id_t_(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public void setId(SWIGTYPE_p_unsigned_char value) {
      ExampleJNI.example_location_id_t__id_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
  }

  public SWIGTYPE_p_unsigned_char getId() {
    long cPtr = ExampleJNI.example_location_id_t__id_get(swigCPtr, this);
    return (cPtr == 0) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false);
  }

  public void setPhy_idx(SWIGTYPE_p_uint32_t value) {
    ExampleJNI.example_location_id_t__phy_idx_set(swigCPtr, this, SWIGTYPE_p_uint32_t.getCPtr(value));
  }

  public SWIGTYPE_p_uint32_t getPhy_idx() {
    return new SWIGTYPE_p_uint32_t(ExampleJNI.example_location_id_t__phy_idx_get(swigCPtr, this), true);
  }

  public example_location_id_t_() {
    this(ExampleJNI.new_example_location_id_t_(), true);
  }

}

1 个答案:

答案 0 :(得分:5)

在没有给出任何额外信息的情况下,SWIG默认假设您希望将事物包装为可以返回并从一个函数传递到另一个函数的类型,即使它无法在目标语言中有意义地包装。

每当您看到一个以SWIGTYPE_...开头的类型时,这意味着SWIG不知道如何生成更好的包装器,这是它设法提出的最佳选择。

SWIG确实提供了默认的图表,可以帮助您:

  • 对于setPhy_idx(uint32_t value);,您需要在界面中添加:

    %include "stdint.i"
    
    void setPhy_idx(uint32_t value);
    

    并且可以在目标语言中使用可以代表uint32_t的类型。

  • 对于setId(unsigned char *value);,它实际上取决于value - 如果它是NULL终止的字符串,您可以执行以下操作:

    %apply char * { unsigned char * };
    
    void setId(unsigned char *value);
    

    将以您的目标语言使用String

    如果你想将指针作为整数类型传递,你可以使用类似的东西:

    %apply unsigned long { unsigned char * };
    
    void setId(unsigned char *value);
    

    代替。

    如果unsigned char *value是指向单unsigned char的指针,则可以执行以下操作:

    %include "typemaps.i"
    %apply unsigned char *INPUT { unsigned char *value };
    
    void setId(unsigned char *value);
    

    指示SWIG将poitner视为单个指针。 (如果它也是一个指针,这可以应用于uint32_t