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