Hi,

Using swig, how do you interface to a C++ class with abstract and virtual methods?

In Python, I'm trying to use C++ code for managing a tree (the simplified version is below). The file "mytree.h" has an abstract class called "Node" and a class called "RBTree" which uses "Node" specifically at the function RBTree::Insert(Node* newNode). The file "test_mytree.py" derives the base class Node and calls it "MyNode" then attempts to insert the node in the RBTree object "T" (not shown in the simplified version below). Unfortunately, the C++ does not recognize that MyNode is derived from class Node. The error is shown below:

I've tried reading up on several methods such as using "directors", but to no avail. Does Swig's director apply here? If so, I'd appreciate an example on how to properly use it in my case. If not, is there another technique that Swig provides? I'm hoping I don't have to resort to using Boost or modifying the implementation of the tree algorithm.

. . . . . . . . . . . . . . . . . . . . . . . . .
output error message:
. . . . . . . . . . . . . . . . . . . . . . . . .
$ python test_mytree.py 
Creating tree:
here at creating RBTree()
here at init,() value = 10

Traceback (most recent call last):
  File "test_mytree.py", line 25, in <module>
    main(sys.argv[1:])
  File "test_mytree.py", line 21, in main
    T.Insert(tmpnode)
  File "/home/betamaz/Visualization/Report_IE6.exe/dllmap/interval_tree/tmp_cpython/mytree.py", line 100, in Insert
    def Insert(self, *args): return _mytree.RBTree_Insert(self, *args)
TypeError: in method 'RBTree_Insert', argument 2 of type 'Node *'
$

- - - - - - - - - - - - - - - - - - - - - - - - -
mytree.i
- - - - - - - - - - - - - - - - - - - - - - - - -
module(directors="1") mytree
%{
#include "mytree.h"
%}

%include "mytree.h"

%feature("director") Node;

- - - - - - - - - - - - - - - - - - - - - - - - -
mytree.h
- - - - - - - - - - - - - - - - - - - - - - - - -
#ifndef MYLIST_H_
#define MYLIST_H_

#include <Python.h>

class Node {
public:
  Node();
  virtual int GetValue() const = 0;
  virtual void Print() const;
};

class RBTree{
public:
      RBTree();
      void Insert(Node *);
};

#endif

- - - - - - - - - - - - - - - - - - - - - - - - -
mytree.cpp
- - - - - - - - - - - - - - - - - - - - - - - - -
#include "mytree.h"
#include <stdio.h>

RBTree::RBTree()
{ fprintf(stderr, "here at creating RBTree()\n"); }

void RBTree::Insert(Node * newNode)
{ fprintf(stderr, "here at Insert()\n"); }

- - - - - - - - - - - - - - - - - - - - - - - - -
test_mytree.py
- - - - - - - - - - - - - - - - - - - - - - - - -
import mytree
import sys

class MyNode(mytree.Node):
    def __init__(self, v):
        print "here at init,() value =", v
        self.value = v

    def GetValue(self):
        return self.value

    def Print(self):
        print "(", self.value,")"

def main(argv):
    print "Creating tree:"
    T = mytree.RBTree()
    tmpnode = MyNode(10)
    T.Insert(tmpnode)
    print "Done."

if __name__ == "__main__":
    main(sys.argv[1:])


Thank you in advance,
-Atoosaah