【问题标题】:Swig java process std::pair with a class from c++Swig java 处理 std::pair 与来自 C++ 的类
【发布时间】:2019-04-21 19:24:23
【问题描述】:

我正在尝试使用头文件从 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::pairs 如下:

%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 为 Result 和 ShortPair (std::pair) 类生成 java 代码没有任何问题。但在所有情况下,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. 有奇怪的pair classes,默认情况下在java-code中生成和使用。 例如类 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;
  }
}

如何使用 swig 为带有自定义对象的 std::pair 生成正确的 java 包装器,并避免自动生成 SWIGTYPE_p_Result、SWIGTYPE_p_std__pairT_lib__Result_std__string_t?

【问题讨论】:

    标签: java c++ swig std-pair


    【解决方案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>>;
    

    【讨论】:

    • 感谢您的回复!这几乎解决了我的问题。只剩下一个问题是生成 SWIGTYPE_p_Result 而不是在 ResultStringPair 代码中使用已经生成的 Result 类: public void setFirst(SWIGTYPE_p_Result value) { vselibJNI.PairResultString_first_set(swigCPtr, this, SWIGTYPE_p_Result.getCPtr(value)); }
    • 我认为解决了。我添加了 %inline %{ struct Result {}; %} 在 %include "lib.h" 之前进入 swig-script 文件,以防止生成 SWIGTYPE_p_Result 并在 java 对结构中使用 Result 对象
    • 我有点困惑 - 因为你的 lib.h 中有 struct Result %include "lib.h" 应该足够了。
    猜你喜欢
    • 2020-08-12
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 2018-11-11
    相关资源
    最近更新 更多