[PyKDE] PyKDE and libkdegames

Bjorn Pettersen BPettersen at narex.com
Mon Jun 10 22:30:01 BST 2002


> From: Jim Bublitz [mailto:jbublitz at nwinternet.com] 
> 
> On 10-Jun-02 Neil Stevens wrote:
> > Could anyone give me any advice on how to make a wrapper for
> > libkdegames (or any of the other extra libs for that matter) in
> > the way PyKDE wraps kdelibs?
>  
> > My first obvious steps would be to look on a cvs or the sip docs,
> > but lacking both I hope for some help here. :-)
> 
> Basically, there are only a few simple rules for generating sip
> description files (.sip) from C++ headers:
> 

0a. Delete all methods you don't want to expose to Python (although
point 5 below still holds).
0b. Delete all operator overloads (you'll have to write %MemberCode to
access those).

> 1. Delete any forward declarations
> 2. Change 'class someClass : public QWidget' to 
> 'class someClass : QWidget'

But only if you have given a definition for QWidget in one of your sip
files, i.e. there is no need to expose the inheritance relationship if
it doesn't buy you anything. E.g. the following is perfectly fine:

  foo.h
  
    class A {
    public:
        int foo();
    };
    class B : public A {
    public:
        int bar();
    };

  foo.sip

    class B {
    %HeaderCode
    #include "foo.h"
    %End
    public:
        int foo();
        int bar();
    };

This can be useful if you're inheriting from a templatized class.

> 3. Add %HeaderCode block to include C++ .h file
> 4. Delete all argument variable names (but not default values).
> 5. Delete all protected variables, anything private EXCEPT
> ctors/dtors. Delete public dtors. ALL pure virtual methods must
> be included, even if private.
> 6. Any methods which pass int&, int*, bool&, bool* etc. (basic
> types, not objects) or char ** will require handwrittten code
> (%MemberCode). Same if you want to pass/return Python data
> structures (lists, tuples, etc)

A simple example is in kcharsets.sip

> 7. Anything template based (eg QList <QString>) will require either
> handwritten code or a %MappedType.

A simple example is in the PyQt distribution in qpair.sip. Note that
specific instantiations of a templatized class work fine as long as SIP
doesn't see the template, e.g:

  ivec.h:

     #include <vector>
     typedef std::vector<int> IntVector;

  ivec.sip:

     class IntVector {
     %HeaderCode
     #include "ivec.h"
     %End
     public:
         void push_back(int);
         int size();
     };

> 8. Eliminate duplicate typedefs if any
> 9. Namespaces need some special handling, mostly in naming objects 
> in namespaces - see KParts stuff

I.e. if subclassing from a class in the same namespace you need to
prefix with the namespace, e.g:

  namespace foo {

  class A {...};
  class B : foo::A {...};

  };

Note also that SIP requires a semicolon after the closing brace of the
namespace (C++ doesn't) -- otherwise SIP will give an "Unexpected end of
input" error.

Finally, namespaces are implemented as classes within classes in the
generated Python file (i.e. not as modules or packages) this may or may
not be an issue for you.

Of course, if you want to get rid of the namespace you can use a 'using'
directive in the %HeaderCode section:

  class string {
  %HeaderCode
  #include <string>
  using namespace std;
  %End
  public:
      const char* c_str();
  };

> 10. There are some minor syntax adjustments needed - for example
> 'unsigned short int' probably won't parse, but 'ushort' will.

-- bjorn




More information about the PyQt mailing list