Call operator in experimental cpp class definition

38 views
Skip to first unread message

Michael Hamann

unread,
Feb 24, 2015, 9:53:01 AM2/24/15
to cython...@googlegroups.com
Hi,

after discovering the experimental support for defining and implementing cpp
classes in Cython I thought this could be a really nice feature for wrapping
Python callbacks in cpp objects so they can be passed to functions accepting
cpp callbacks.

However either I did not understand how to declare operator() in cpp classes
or there is a bug/missing feature.

Example:

# distutils: language = c++
# cython: experimental_cpp_class_def=True

cdef cppclass CallbackWrapper:
void* callback
__init__(object callback):
this.callback = <void*>callback
void operator()(int y):
cdef object myCallback = <object>callback
myCallback(y)

This code gives two errors for the line with operator():

Function cannot return a function
Compiler crash in ControlFlowAnalysis

Note that __call__ (I thought maybe this is similar to __init__) doesn't work
either as it doesn't seem to have any special meaning in this context.

I'm using Cython version 0.22.

I managed to get a working example by replacing "operator()" by some name that
is replaced by operator() later using a macro:

## test.h:

#include <iostream>

#define cython_call_operator operator()

class TestClass {
public:
template <typename F>
void callF(F &f) {
std::cout << "Calling f with 5" << std::endl;
f(5);
}
};

## test.pyx:

# distutils: language = c++
# cython: experimental_cpp_class_def=True

from cython.operator import dereference

cdef extern from "test.h":
cdef cppclass _TestClass "TestClass":
void callF[F](F &f)

def callbackFunc(y):
print(y)

cdef cppclass CallbackWrapper:
void* callback
__init__(object callback):
this.callback = <void*>callback
void cython_call_operator(int y):
cdef object myCallback = <object>callback
myCallback(y)

cdef _TestClass myTest

cdef CallbackWrapper* wrapper = new CallbackWrapper(callbackFunc)
myTest.callF(dereference(wrapper))


Btw. this is just a "hello world" example of course, in reality I want to
provide a Python wrapper for "TestClass" that transparently instantiates the
wrapper object for the Python callback and passes it to the underlying cpp
method. Note that memory management is no issue here as the callback won't be
used anymore after the cpp method has returned.

Thanks in advance,
Michael

PS: What exactly is the status of this "experimental" cpp class definition
feature?
Reply all
Reply to author
Forward
0 new messages