Skip to content

Instantly share code, notes, and snippets.

@YukiSakamoto
Last active August 23, 2023 15:20
Show Gist options
  • Save YukiSakamoto/5b60e3d11dd8b85bcbe8 to your computer and use it in GitHub Desktop.
Save YukiSakamoto/5b60e3d11dd8b85bcbe8 to your computer and use it in GitHub Desktop.
Callback function via Cython
#include "Callback.hpp"
#include <iostream>
IntHolderCallback::IntHolderCallback(iMethod method, void *user_data)
{
this->_method = method;
this->_user_data = user_data;
}
int
IntHolderCallback::cy_execute(IntHolder *parameter)
{
//std::cout << __func__ << std::endl;
return _method(parameter, _user_data);
}
//============================================================
//
Callback::Callback()
{
is_cy_call = true;
}
Callback::~Callback()
{
}
Callback::Callback(Method method, void *user_data)
{
is_cy_call = true;
this->_method = method;
this->_user_data = user_data;
}
double Callback::cy_execute(void *parameter)
{
return _method(parameter, _user_data);
}
#ifndef CALLBACK_H_
#define CALLBACK_H_
#include <iostream>
class IntHolder {
public:
IntHolder(int a, int b) : num_(a), value_(b) {;}
IntHolder(IntHolder &tmplte) : num_(tmplte.num_), value_(tmplte.value_){;}
int get_number(void) { return this->num_; }
int get_value(void) { return this->value_; }
private:
int num_;
int value_;
};
class IntHolderCallback {
public:
typedef int (*iMethod)(IntHolder *param, void *user_data);
IntHolderCallback(){;}
IntHolderCallback(iMethod method, void *user_data);
virtual ~IntHolderCallback(){;}
int cy_execute(IntHolder *param);
private:
iMethod _method;
void *_user_data;
};
class Callback {
public:
typedef double (*Method)(void *param, void *user_data);
Callback();
Callback(Method method, void *user_data);
virtual ~Callback();
double cy_execute(void *parameter);
bool IsCythonCall()
{
return is_cy_call;
}
protected:
bool is_cy_call;
private:
Method _method;
void *_user_data;
};
#endif
# vim:set foldmethod=marker:
from cython.operator cimport dereference as deref
import sys
ctypedef double (*Method)(void *param, void *user_data)
ctypedef int (*iMethod)(IntHolder *param, void *user_data)
cdef extern from "Callback.hpp":
cdef cppclass Callback:
Callback(Method method, void *user_data)
double cy_execute(void *paramter)
cdef extern from "Callback.hpp":
cdef cppclass IntHolder:
IntHolder(int, int)
IntHolder(IntHolder&)
int get_number()
int get_value()
cdef cppclass IntHolderCallback:
IntHolderCallback(iMethod method, void *user_data)
int cy_execute(IntHolder *param)
cdef double callback(void *parameter, void *method):
return (<object>method)(<object>parameter)
#{{{
cdef class PyCallback:
cdef Callback *thisptr
def __cinit__(self, method):
self.thisptr = new Callback(callback, <void*>method)
def __dealloc__(self):
if self.thisptr:
del self.thisptr
cpdef double execute(self, parameter):
return self.thisptr.cy_execute(<void*>parameter)
#}}}
cdef class PyIntHolder: #{{{
cdef IntHolder *thisptr
def __cinit__(self, int num, int num2):
self.thisptr = new IntHolder(num, num2)
def __dealloc__(self):
if self.thisptr:
del self.thisptr
def get_number(self):
return self.thisptr.get_number()
def get_value(self):
return self.thisptr.get_value()
cdef PyIntHolder PyIntHolder_from_Cpp_IntHolder(IntHolder *p):
cdef IntHolder *new_obj = new IntHolder(deref(p))
r = PyIntHolder(0, 0)
del r.thisptr
r.thisptr = new_obj
return r
#}}}
cdef int int_callback(IntHolder *parameter, void *method):
cdef PyIntHolder arg = PyIntHolder_from_Cpp_IntHolder(parameter)
#cdef int a = (<object>method)(PyIntHolder_from_Cpp_IntHolder(parameter) )
cdef int a = (<object>method)(<object>arg)
return a
cdef class PyIntHolderCallback: #{{{
cdef IntHolderCallback *thisptr
def __cinit__(self, method):
self.thisptr = new IntHolderCallback(int_callback, <void*>method)
def __dealloc__(self):
if self.thisptr:
del self.thisptr
cpdef int execute(self, PyIntHolder parameter):
return self.thisptr.cy_execute(parameter.thisptr)
#}}}
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
source = [
'Callback.cpp',
'./Front.pyx'
]
#numpy_include = ['/System/Library/Frameworks/Python.framework/Versions/Current/Extras/lib/python/numpy/core/include']
setup(
cmdclass = dict(build_ext = build_ext),
ext_modules = [
Extension(
'MyCallback',
source,
#include_dirs = numpy_include,
language='c++',
)
]
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment