Matthieu Brucher wrote:

    Doing the wrapping in an object oriented way is difficult, and maybe
    not that useful. This does not prevent the API exposed to python
    to be
    OO, of course.



I have some difficulties to do this in an automated way...
I'm trying now to make a derived object from my function, without templates and, I'm hoping so, with a correct interface i.e. double + 2*int to save make the conversions with numpy arrays.
    > That works great for C then, not that well for C++...
    Well, this is an inherent problem of C++ when you try to use it from
    other languages, but let's not start this (again :) ),



:D

    The example shows basic wrapping, and some facilities provided by
    numpy to help. Again, ctype is pretty efficient as long as you do not
    need to do convertion. If you call it thousand of times, it will be
    slow, but this is more or less inherent to python (function calls are
    nowhere near as fast as in a compiled language, at least for now).



It's for optimization, so the function will be called several hundreds of times, I suppose, and I tried porting the whole function to Python, but I'm not sure that the Python version behaves like the C++ version - the results are not identic, so... -, thus the wrapping.
A couple of hundred times is OK if the called function is doing something. I once benchmarked ctypes with respect to function calling, and I could do several hundred of thousand of calls/s, if I remember correctly.


It's only one class and one method + the constructor. Not much but I'm a real beginner in that domain. True, I could use the C API directly...
Ok, I have a simple working example. It is actually much easier than I thought, because no C compiler is involved at all (I was afraid about object layout, vtables and other horrors), only C++.

I attached the example: it shows how to mimic a C++ class in python through a C-like interface. The main difficulty is to be sure that your object get deleted by the python interpreter, which means having a __del__ function. The problem is that you cannot control how python will destroy its things: it may "destroy" ctypes module before your object, which is problematic since you need it to destroy your object. The idea is to "force" python to keep everything in the namespace through a fake second argument to the destructor.

http://docs.python.org/ref/customization.html (comments on __del__ ).

David
# Last Change: Fri Apr 20 11:00 AM 2007 J

from numpy.ctypeslib import ndpointer, load_library

# Load the library
_hellocpp = load_library('hellocpp', '.')

class Hello:
    def __init__(self):
        self._hdl   = _hellocpp.init_hello()

    def __del__(self, close_func = _hellocpp.destroy_hello):
        if not (self._hdl == 0):
            close_func(self._hdl)
            self._hdl = 0

h   = Hello()
#include <iostream>

#include "hellocpp.h"

Hello::Hello() 
{ 
    std::cout << "ctor\n";
}

Hello::~Hello() 
{ 
    std::cout << "dtor\n";
}

Hello* init_hello()
{
    /* We;re screwed if Hello ctor throws an exception */
    Hello   *tmp = new Hello();
    return tmp;
}

int destroy_hello(Hello* h)
{
    delete h;
    return 0;
}
/*
 * Last Change: Fri Apr 20 11:00 AM 2007 J
 */

class Hello {
    public:
        Hello();
        ~Hello();
};

typedef struct Hello Hello;

extern "C" {
    extern Hello* init_hello();
    extern int destroy_hello(Hello* h);
}
CC      = colorgcc
CXX     = colorgcc

LD      = g++

PYTHONINC       = -I/usr/include/python2.5
NUMPYINC        = -I/usr/lib/python2.5/site-packages/numpy/core/include

WARN    = -W -Wall 

CFLAGS  = $(WARN) $(PYTHONINC) $(NUMPYINC)

hellocpp.so: hellocpp.o
        $(LD) -shared -o $@ $< -Wl,-soname,$@

hellocpp.o: hellocpp.cpp
        $(CXX) -c $(CFLAGS) -fPIC $<

clean:
        rm -f *.o
        rm -f *.so
_______________________________________________
Numpy-discussion mailing list
Numpy-discussion@scipy.org
http://projects.scipy.org/mailman/listinfo/numpy-discussion

Reply via email to