Reputation: 789
I am trying to use a pointer inside a cython class.
the outside_class
ctypedef
works like a charm but i am unable to get the inside_class
to work. a "ctypedef statement not allowed here" error is thrown and i don't understand what is wrong.
Why should this work
the outside_class
typdef works so i assumed it should also work inside. I was unable to get it to work so i tried to find some more information on it, unfortunately all information is about the outside_class
example so i do not know whether the other is allowed or even possible. to me it seems the only difference is the self
argument.
Why do i want this to work
This class is going to contain 35+ functions with the same arguments, when used only a part of those functions is called in a specific order. When initializing i want to create an array with all functions in the correct order. Of course a different way of doing so is also welcome.
updated code sample 14-02
test A & B work but C & D do not, error message is given below.
My code:
ctypedef int (*outside_class)()
ctypedef int (*inside_class)(Preprocess)
cdef int outside_foo():
return 12
cdef int outside_bar(Preprocess self):
return 20
cdef class Preprocess:
cdef int inside_foo(self):
return 18
cdef int inside_bar(self):
return 14
cdef int inside_sek(self):
return 16
def __init__(self):
cdef outside_class test_A
test_A = &outside_foo
print( test_A() )
cdef inside_class test_B
test_B = &outside_bar
print( test_B(self) )
cdef inside_class test_C
test_C = &self.inside_foo
#print( test_C(self) )
print( "no error, yet.." )
cdef inside_class test_D
test_D = &self.inside_foo
print( test_D(self) )
error
/home/boss/.pyxbld/temp.linux-x86_64-2.7/pyrex/aa/preprocessing/preprocessing.c: In function ‘__pyx_pf_7aa_13preprocessing_13preprocessing_10Preprocess___init__’:
/home/boss/.pyxbld/temp.linux-x86_64-2.7/pyrex/aa/preprocessing/preprocessing.c:938:18: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
__pyx_v_test_C = (&((struct __pyx_vtabstruct_7aa_13preprocessing_13preprocessing_Preprocess *)__pyx_v_se
^
/home/boss/.pyxbld/temp.linux-x86_64-2.7/pyrex/aa/preprocessing/preprocessing.c:955:18: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
__pyx_v_test_D = (&((struct __pyx_vtabstruct_7aa_13preprocessing_13preprocessing_Preprocess *)__pyx_v_se
^
12
20
no error, yet..
Segmentation fault (core dumped)
Upvotes: 0
Views: 1054
Reputation: 231385
cython
raises the error as soon as it sees the cdeftype
within the class
definition. It hasn't even looked at, or run, the &self.inside_foo
assignment:
0000:~/mypy/cython3$ cython stack42214943.pyx -a
Error compiling Cython file:
------------------------------------------------------------
...
cdef int outside_foo():
return 12
cdef class Preprocess:
ctypedef int (*inside_class)(Preprocess)
^
------------------------------------------------------------
stack42214943.pyx:8:4: ctypedef statement not allowed here
If I try cdef int(*)(Preprocess) inside_test
, I get a Syntax error in C variable declaration
. Again before the self
line.
(edit)
With the following code I can create and run both a python list of 3 functions and a C
array of the same.
def __init__(self):
cdef outside_class test_A
test_A = &outside_foo
print( test_A() )
cdef inside_class test_B
test_B = &outside_bar
print( test_B(self) )
print(self.inside_foo())
cpdef evalc(self):
# cdef int (*inside_array[3]) (Preprocess)
cdef inside_class inside_array[3]
inside_array[0] = self.inside_foo
inside_array[1] = self.inside_bar
inside_array[2] = self.inside_sek
print('eval inside_array')
for fn in inside_array:
print(fn(self))
def evals(self):
alist = [self.inside_foo, self.inside_bar, self.inside_sek]
alist = [fn(self) for fn in alist]
print(alist)
self.evalc()
In an Ipython session I can compile and import this, and run it with:
In [3]: p=stack42214943.Preprocess()
12
20
18
In [4]: p.evals()
[18, 14, 16]
eval inside_array
18
14
16
In [5]: p.evalc()
eval inside_array
18
14
16
I haven't figured out how to define and access inside_array
outside of the evalc
function. But maybe I don't need to. And instead of printing, that function could return the 3 values as some sort of int
array or list.
Upvotes: 1