Как передать std :: vector <UserDefinedClass>с данными в Java через Swig? - PullRequest
0 голосов
/ 14 мая 2019

У меня есть следующая библиотека 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 голосов
/ 14 мая 2019

Это должно работать.Заказ имеет значение.Обязательно определите классы перед их использованием:

%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 {}
};

%}
...