SWIG覆盖功能或修改C ++结果对象

时间:2012-01-17 11:51:31

标签: swig

我有一个SWIG生成的函数如下:

SWIGINTERN PyObject *_wrap_StrVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
  PySliceObject *arg2 = (PySliceObject *) 0 ;
  void *argp1 = 0 ;
  int res1 = 0 ;
  PyObject * obj0 = 0 ;
  PyObject * obj1 = 0 ;
  std::vector< std::string,std::allocator< std::string > > *result = 0 ;

  if (!PyArg_ParseTuple(args,(char *)"OO:StrVector___getitem__",&obj0,&obj1)) SWIG_fail;
  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
  if (!SWIG_IsOK(res1)) {
    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StrVector___getitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
  }
  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
  {
    if (!PySlice_Check(obj1)) {
      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StrVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
    }
    arg2 = (PySliceObject *) obj1;
  }
  try {
    result = (std::vector< std::string,std::allocator< std::string > > *)std_vector_Sl_std_string_Sg____getitem____SWIG_0(arg1,arg2);
  }
  catch(std::out_of_range &_e) {
    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
  }

  *****1*****
  ***//I want to modify or print variable result here like printf("%s", result->c_str());***

  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
  return resultobj;
fail:
  return NULL;
}

我需要在位置1打印变量结果(如代码中所述)。 Typemap(argout)似乎没有多大帮助。

1 个答案:

答案 0 :(得分:2)

我假设您要修改的函数是Python中的std::vector<std::string> __getitem__例程。

修改或拦截返回值结果的最简单,最安全的方法实际上是在Python端使用%feature("pythonappend")进行,例如:

%module test

%{
#include "test.h"
%}

%include "pyabc.i"
%include "std_vector.i"
%include "std_string.i"

%feature("pythonappend") std::vector<std::string>::__getitem__ %{
  # do something
  print val
%}

%include "test.h"

%template (StringVector) std::vector<std::string>;

这是修改结果的最简单方法的原因是修改结果的下一个最简单的方法是需要更改返回类型的类型映射 - 在本例中为std::string。要做到这一点,你最终会改变现有的std::string类型图,这有点混乱。

或者,您可能希望使用%exception指令在$action之后放置一些C ++代码,但除非这是为了验证返回的结果,否则感觉非常hackish。