Как использовать генерируемые SWIG структуры C в Java в качестве входных данных для функций C через SWIG / JNI - PullRequest
3 голосов
/ 23 ноября 2011

У меня есть файл интерфейса SWIG, который предоставляет некоторые функции C (через JNI) моему Java-приложению, и эти структуры C используются в качестве входных данных для функции C (через SWIG / JNI).SWIG генерирует структуру как класс Java, но я не уверен, как установить свойства структур, так как установщики принимают сгенерированный тип SWIG.Мне нужно установить свойства структур перед передачей его в качестве входных данных в функцию C из моего класса Java.example_location_id_t_ - это класс, который мне нужно передать, но установщики для Id и Phy_idx принимают следующие типы SWIG.Как мне заполнить SWIGTYPE_p_unsigned_char и SWIGTYPE_p_uint32_t, чтобы я мог установить свойства Id и Phy_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);
  }

}

1 Ответ

5 голосов
/ 23 ноября 2011

Без предоставления какой-либо дополнительной информации 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 обрабатывать пуитнер как единый указатель.(Это может быть применено для uint32_t, если это тоже указатель)

...