使用SWIG用虚拟方法包装C++类并在Python中重写它们

Using SWIG to wrap C++ class with virtual methods and overriding them in python

调用python回调时,我正在尝试"pythonize"方法参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    %module (directors="1") py_test
    %feature("director") mgr;


    struct hdr_val {
        const char *hdr;
        const char *val;
    };

    struct hdr_list {
        int count;
        struct hdr_val *elems;
    };


    struct myinfo {
      int   newcid;                
      int   oldcid;                
      const char *uri;    
      struct hdr_list hlist;
    };

    %{
    PyObject*
    make_hdrlist(const struct hdr_list *hl) {
      PyObject* result;

      result = PyList_New(hl->count);
      for(int i = 0; i count; i++)
         PyList_SetItem(result, i, Py_BuildValue("(ss)", hl->elems[i].hdr, hl->elems[i].val));

      return result;    
    }
    %}


    class mgr {
    public:
       mgr() { }
       virtual void doit();

       virtual void done(const struct myinfo* i)  // Will be redefined in python
       {
       }
    };

    %typemap(out) struct myinfo* i {

        $result = Py_BuildValue("(iiso)", $1->newcid, $1->oldcid, $1->uri, make_hdrlist(&$1->hlist));

    }

所以在python中,我可以执行以下操作:

1
2
3
4
    import py_test
    class pymgr(py_test.mgr):
       def done(self, info):
         oldcid,newcid,uri,hlist = info

例如,我希望python中的info参数是tuple("iiso")而不是swig包装器对象。

不幸的是,由于某种原因,斯威格忽略了我的江户。有什么想法吗?


好的,我找到答案了类型图应该放在类管理器之前。

1
2
3
4
%typemap(directorin) myinfo const * {
    $input = Py_BuildValue("(iiso)", $1_name->newcid, $1_name->oldcid,
                           $1_name->uri, make_hdrlist(&$1_name->hlist));
}