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

发布于 2024-12-17 18:45:28 字数 2660 浏览 0 评论 0原文

我有一个 SWIG 接口文件,它向我的 Java 应用程序公开一些 C 函数(通过 JNI),并且这些 C 结构用作 C 函数的输入(通过 SWIG/JNI)。 SWIG 将结构生成为 Java 类,但我不确定如何设置结构属性,因为设置器采用 SWIG 生成的类型。我需要先设置结构属性,然后再将其作为输入从 Java 类传递到 C 函数。 example_location_id_t_ 是我需要传递的类,但 IdPhy_idx 的设置器采用以下 SWIG 类型。如何填充 SWIGTYPE_p_unsigned_charSWIGTYPE_p_uint32_t 以便设置 IdPhy_idx 属性>SWIGTYPE_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);
  }

}

I have a SWIG interface file that exposes some C functions (via JNI) to my Java application and these C structures are used as input into the C function (via SWIG/JNI). SWIG generates the structure as a Java class, but I'm unsure how to set the structures properties as the setters take a SWIG generated type. I need to set the structures properties before passing it as input into the C function from my Java class. example_location_id_t_ is the class I need to pass, but the setters for Id and Phy_idx take the below SWIG types. How do I populate the SWIGTYPE_p_unsigned_char and SWIGTYPE_p_uint32_t so that I can set the Id and Phy_idx properties of the SWIGTYPE_p_uint32_t class?

setId(SWIGTYPE_p_unsigned_char value) and 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);
  }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云醉月微眠 2024-12-24 18:45:28

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

每次您看到以 SWIGTYPE_... 开头的类型时,都意味着 SWIG 不知道如何生成更好的包装器,而这是它设法想出的最好的包装器。

SWIG 确实提供了默认类型映射,可以在这里为您提供帮助:

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

    %include “stdint.i”
    
    无效setPhy_idx(uint32_t值);
    

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

  • 对于 setId(unsigned char *value); 这完全取决于 value 实际是什么 - 如果它是一个 NULL 终止的字符串,你可以这样做像这样:

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

    和一个字符串将用于您的目标语言。

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

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

    相反。

    如果unsigned char *value是指向单个unsigned char的指针,您可以这样做:

    %include“typemaps.i”
    %应用无符号字符*输入{无符号字符*值};
    
    void setId(unsigned char *value);
    

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

Without being given any extra information SWIG defaults to assuming you want things wrapped as a type that can be returned and passed from one function to another, even if it can't be wrapped meaningfully in the target language.

Every time you see a type that begins SWIGTYPE_... it means SWIG didn't know how to generate a better wrapper and this was the best it managed to come up with.

SWIG does provide default typemaps that can help you here though:

  • For setPhy_idx(uint32_t value); all you need to add in your interface is:

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

    and a type which can represent a uint32_t will be used in the target language.

  • For setId(unsigned char *value); it depends quite what value actually is - if it's a NULL terminated string you can do something like:

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

    and a String will be used in your target language.

    If you wanted to pass the pointer as an integer type you could use something like:

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

    instead.

    If unsigned char *value is a pointer to a single unsigned char you could do:

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

    which instructs SWIG to treat the poitner as a single pointer. (This could be applied for the uint32_t if it was a pointer too)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文