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

时间:2019-05-13 23:23:00

标签: java c++ 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之前的版本。如果我确实错过了,请避免犯错。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分: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 {}
};

%}