如何通过 Swig 将带有数据的 std::vector<UserDefinedClass> 传递给 Java?

How to pass a std::vector<UserDefinedClass> with data to Java via Swig?

我有以下 C++ 库,我想在 Java 中使用它,使用 Swig 生成必要的粘合代码。但是,我发现很难将用户定义对象的向量发送到具有一些数据的 C++。我尝试使用 std_vector.i 但 Swig 仍然生成 SWIGTYPE_p_std_VectorT_namespace_Beer ,它与 SwigVector 实例不匹配。

%module pub

%include "std_vector.i"
namespace std {
  %template(SwigVector) std::vector<Beer>;
}  

%{
#include "Pub.h"
#include "MyPub.h"
#include "Beer.h"   
using namespace pub;
%}

%include "Pub.h"    
...
namespace order{
class OrderTracker
{
public:
    class OrderListener
    {
    public:
        OrderListener() : orderTracker_{nullptr} {}
        virtual void onNewOrder(OrderTracker&) = 0;
    private:
        friend class OrderTracker;
        void setOrderTracker(OrderTracker* orderTracker)
        {
            orderTracker_ = orderTracker;
        }
        OrderTracker* orderTracker_;
    };
    void addOrderListner(OrderListener&);
};
class Status;
...
} // end namespace order

namespace pub{
class Pub
{
public:
    virtual ~Pub() = default;
    virtual void initOrder() = 0;
    virtual std::vector<Beer> getBeers() = 0;
    ...
};

class MyPub : public Pub
{
public:
    void initOrder() override;
    std::vector<Beer> getBeers() override;
    void generateBill() override;
    ...
private:
    order::OrderTracker* orderTracker;
    class MyOrderListener : public order::OrderTracker::OrderListener
        {
        public:
            explicit MyOrderListener(MyPub* pub) { this->pub_ = pub; }
            ~MyOrderListener() { delete pub_; }
            void onNewOrder(order::OrderTracker& orderTracker) = override;
        private:
            MyPub* pub_;
        };
        MyOrderListener* listener; // orderTracker->addOrderListner(listener);
};

enum class BeerType
{
    House   ,
    Lager   ,
    Pale    ,
    IPA
};

class Beer
{
public:
    Beer() : type{BeerType::House}, price{5.99} {}
    ~Beer() = default;

    BeerType getType() {return this->type};
    float getBeerPrice() {return this->price};

private:
    BeerType type;
    float price;

    void setPrice(float price);
    void setType(BeerType type);
};
} // namespace pub ends

以下是我期望的行为。

public class main
{
    public static void main(String argv[])
    {
        System.loadLibrary("mypub");
        MyPub pub = new MyPub();
        pub.initOrder();
        while(money > 1000)
        {
         SwigVector beers = pub.getBeers();
            for(int i =0; i<beers.size(); ++i){
            beers[i].getPrice();
            }
        }
   }
}

P.S。大多数问题要么包含原始数据类型,要么是 Swig 3.0 之前的版本。如果我确实遗漏了任何内容,请不要犯错。任何帮助将不胜感激。

这应该有效。订单很重要。确保在使用它们之前定义 类:

%module pub

%include "std_vector.i"

%inline %{

enum class BeerType
{
    House,
    Lager,
    Pale,
    IPA
};

class Beer
{
public:
    Beer() : type{BeerType::House}, price{5.99f} {}
    ~Beer() = default;

    BeerType getType() {return this->type; }
    float getBeerPrice() {return this->price; }

private:
    BeerType type;
    float price;

    void setPrice(float price) { this->price = price; }
    void setType(BeerType type) { this->type = type; }
};

%}

%template(SwigVector) std::vector<Beer>;

%inline %{

class Pub
{
public:
    virtual ~Pub() = default;
    virtual void initOrder() = 0;
    virtual std::vector<Beer> getBeers() = 0;
    virtual void generateBill() = 0;
};

class MyPub : public Pub
{
public:
    void initOrder() override {}
    std::vector<Beer> getBeers() override { return {Beer(),Beer()}; }
    void generateBill() override {}
};

%}