如何将boost :: tuples :: tuple暴露给Java绑定?

时间:2012-03-12 11:33:30

标签: c++ boost swig

我有boost::tuple的列表。我想通过SWIG将这个元组列表暴露给Java绑定。但是当我尝试编译由SWIG生成的mt wrap.cxx时,我得到以下错误:

d:\xyz\...\vector.h(115) : error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const boost::tuples::tuple<T0,T1>' (or there is no acceptable conversion)
        with
        [
            T0=std::string,
            T1=std::string
        ]
        c:\program files\microsoft visual studio 8\vc\platformsdk\include\guiddef.h(192): or 'int operator ==(const GUID &,const GUID &)'
        while trying to match the argument list '(const boost::tuples::tuple<T0,T1>, const MyTuple)'
        with
        [
            T0=std::string,
            T1=std::string
        ]
        d:\xyz\...\vector.h(111) : while compiling class template member function 'int Vector<T>::index(const T &) const'
        with
        [
            T=MyTuple
        ]
        d:\xyz\...\MyTuple_wrap.cxx(17731) : see reference to class template instantiation 'Vector<T>' being compiled
        with
        [
            T=MyTuple
        ]

有谁能告诉我应该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:3)

目前还不清楚你是如何得出你所显示的错误的。默认情况下,boost::tuple很难包装,但SWIG中似乎没有任何标准接口。在我的测试中,如果不手动编写接口文件,我无法接近您所看到的错误。

但是我使用以下接口文件成功地包装了boost的元组:

%{
#include <boost/tuple/tuple.hpp>
%}

namespace boost {
  template <typename T1=void, typename T2=void, typename T3=void> 
  struct tuple;

  template <>
  struct tuple<void,void,void> {
  };

  template <typename T1>
  struct tuple<T1, void, void> {
    tuple(T1);
    %extend {
      T1 first() const {
        return boost::get<0>(*$self);
      }
    }
  };

  template <typename T1, typename T2>
  struct tuple <T1, T2, void> {
    tuple(T1,T2);
    %extend {
      T1 first() const {
        return boost::get<0>(*$self);
      }
      T2 second() const { 
        return boost::get<1>(*$self);
      }
    }
  };

  template <typename T1, typename T2, typename T3> 
  struct tuple <T1,T2,T3> {
    tuple(T1,T2,T3);
    %extend {
      T1 first() const {
        return boost::get<0>(*$self);
      }
      T2 second() const {
        return boost::get<1>(*$self);
      }
      T3 third() const {
        return boost::get<2>(*$self);
      }
    }
  };
}

基本上它所做的就是为你可能关心的元组的每个特化添加访问器函数。只需在Java或其他语言中使其最低限度就足够了。您可能希望对此进行扩展以涵盖更大的元组。如果您的元组不是不可变的,那么您可能希望使成员函数得到/设置。

我能够使用SWIG模块进行测试:

%module test

%include "boost_tuple.i"

%template(TestTuple) boost::tuple<int, double, char>;

%template(SingleTuple) boost::tuple<char>;

%inline %{
boost::tuple<int, double, char> func1() {
  return boost::make_tuple(3, 2.0, '1');
}

void test1(boost::tuple<int, double, char>) {
}

%}

使用以下Java正常工作:

public class run {
  public static void main(String[] argv) {
    System.loadLibrary("test");
    TestTuple t = test.func1();
    System.out.println("1: " + t.first() + " 2: " + t.second() + " 3: " + t.third());
    test.test1(test.func1());
    test.test1(new TestTuple(0, 0.0, '0'));
  }
}