Swig java-процесс std :: pair с классом из c ++

Я пытаюсь перейти с c ++ на java DLL с файлом заголовка lib.h

enum class Code : uint32_t
{
        ok = 0,
        cancelled = 1,
};  

struct Result
{
    Result(): m_code(Code::ok) {}
    Result(Code code, const std::string& t = std::string()) :m_code(code), m_text(t) {}
    Code code() const { return m_code; }
    const std::string& text() const { return m_text; }

private:
    Code m_code;
    std::string m_text;
};

class IApp
{
public:
    virtual std::pair<std::uint8_t, std::uint8_t> systemModeInt() = 0;
    virtual std::pair<Result, std::uint8_t> systemMode() = 0;
    virtual std::pair<Result, std::string> objectName() = 0;
    virtual std::pair<Result,std::vector<uint8_t>> readParameters() = 0;
}

мой скрипт swig, который обрабатывает std :: pair, выглядит следующим образом:

%include <std_pair.i>
#include "lib.h"

%template(ShortPair) std::pair<std::uint8_t, std::uint8_t>;
%template(ResultStringPair) std::pair<Result, std::string>;
%template(ResultShortPair) std::pair<Result, std::uint8_t>;
%template(ResultVectorPair) std::pair<Result,std::vector<uint8_t>>;

Я вижу, что swig без проблем генерирует java-код для классов Result и ShortPair (std :: pair). Но во всех случаях, когда пара содержит настраиваемый объект, возникают некоторые проблемы:

  1. Результат класса, который анализируется по умолчанию, не распознается и не используется при генерации кода паро-обертки, поэтому в ResultStringPair я вижу SWIGTYPE_p_Result вместо Result:
public class ResultStringPair {
  private transient long swigCPtr;
  protected transient boolean swigCMemOwn;
  public ResultStringPair() {
    this(vselibJNI.new_ResultStringPair__SWIG_0(), true);
  }

  public ResultStringPair(SWIGTYPE_p_Result first, String second) {    this(vselibJNI.new_ResultStringPair__SWIG_1(SWIGTYPE_p_Result.getCPtr(first), second), true);
  }
  1. Есть странная пара классов, которая генерируется и используется по умолчанию в java-коде. Например, создается и используется класс SWIGTYPE_p_std__pairT_lib__Result_std__string_t, хотя ResultStringPair определен и сгенерирован.
public SWIGTYPE_p_std__pairT_lib__Result_std__string_t objectName() {
    return new ...  
}

public class SWIGTYPE_p_std__pairT_lib__Result_std__string_t {
  private transient long swigCPtr;

  protected SWIGTYPE_p_std__pairT_lib__Result_std__string_t(long cPtr, @SuppressWarnings("unused") boolean futureUse) {
    swigCPtr = cPtr;
  }

  protected SWIGTYPE_p_std__pairT_lib__Result_std__string_t() {
    swigCPtr = 0;
  }

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

Как сгенерировать правильные java-оболочки с swig для std :: pair с настраиваемыми объектами и избежать автогенерированных SWIGTYPE_p_Result, SWIGTYPE_p_std__pairT_lib__Result_std__string_t?


person Roman    schedule 21.04.2019    source источник


Ответы (1)


Помимо отсутствующей точки с запятой в вашем файле lib.h вам также необходимо внести следующие изменения в ваш файл SWIG .i, я аннотировал их на месте:

%include <std_pair.i>
%include <std_vector.i> // Missing for vector template
%include <std_string.i> // One of your interface functions had a std::string
%include <stdint.i> // This is needed for uint8_t, uint32_t etc.
%include "lib.h" // This is the most important change - in order to make SWIG read the lib.h file you need to use %include

%template(CharVector) std::vector<uint8_t>; // This was missing and resulted in a SWIGTYPE_ for the last pair
%template(ShortPair) std::pair<std::uint8_t, std::uint8_t>;
%template(ResultStringPair) std::pair<Result, std::string>;
%template(ResultShortPair) std::pair<Result, std::uint8_t>;
%template(ResultVectorPair) std::pair<Result,std::vector<uint8_t>>;
person Flexo    schedule 22.04.2019
comment
Спасибо за ответ! Это почти решило мою проблему. Осталась только одна проблема - создание SWIGTYPE_p_Result вместо использования уже сгенерированного класса Result в коде ResultStringPair: public void setFirst (SWIGTYPE_p_Result value) {vselibJNI.PairResultString_first_set (swigCPtr, this, SWIGTYPE_p_Result value); } - person Roman; 23.04.2019
comment
Думаю решено. Я добавил% inline% {struct Result {}; %} в файл swig-скрипта перед% include lib.h для предотвращения генерации SWIGTYPE_p_Result и использования объектов Result в парных структурах java. - person Roman; 23.04.2019
comment
Я немного запутался - поскольку ваш lib.h содержит struct Result, %include "lib.h" должно быть достаточно. - person Flexo; 24.04.2019