2017-02-13 10 views
0

Я пытаюсь использовать указатель внутри класса cython.Cython, используя указатель функции внутри класса

outside_classctypedef работает как шарм, но я не могу получить inside_class для работы. здесь вызывается ошибка ctypedef, которая не разрешена здесь, и я не понимаю, что не так.

Почему эта работа
outside_class typdef работает, поэтому я предположил, что это должно работать внутри. Мне не удалось заставить его работать, поэтому я попытался найти дополнительную информацию об этом, к сожалению, вся информация о примере outside_class, поэтому я не знаю, разрешено или возможно другое. мне кажется, что единственная разница - это аргумент self.

Почему я хочу, чтобы это работало
Этот класс будет содержать 35+ функции с теми же аргументами, когда используется только часть этих функций вызывается в определенном порядке. При инициализации я хочу создать массив со всеми функциями в правильном порядке. Конечно, другой способ сделать это также приветствуется.

обновленный код образца 14-02

тест А Б & работа, но С & D нет, сообщение об ошибке приведен ниже.

Мой код:

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)) 

ошибка

/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) 
+0

Вам нужно объяснить, почему вы думаете, что это должно сработать и/или почему вам это нужно. Возможно, нет смысла определять/указывать тип C на уровне класса.На одной обучающей странице есть этот комментарий перед 'ctypedef':' # определить глобальное имя для любого типа char, который используется в модуле'. Это и все другие примеры указывают на то, что это удобство именования уровня модуля. – hpaulj

ответ

1

cython вызывает ошибку, как только он видит cdeftype в class определения. Он даже не смотрел, или бежать, в &self.inside_foo назначение:

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 

Если я пытаюсь cdef int(*)(Preprocess) inside_test, я получаю Syntax error in C variable declaration. Опять перед линией self.


(редактировать)

С помощью следующего кода я могу создать и запустить как список питона 3 функций и C массив того же самого.

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() 

В сеансе IPython я могу собрать и импортировать это, и запустить его:

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 

Я не понял, как определить и доступ inside_array за пределами функции evalc. Но, возможно, мне это не нужно. И вместо того, чтобы печатать, эта функция может вернуть 3 значения в виде своего рода массива или списка int.

+0

Приносим извинения, что добавил код, который я чувствовал, должен работать, но почему-то я чего-то не видел. Я обновил свой пример кода. – MaMiFreak

+0

Я не знаю, если это то, что вы хотите, но я могу создать как списки Python, так и C-массивы этих функций 'preprocess' и оценить их. Смотрите мои правки. – hpaulj

+0

Сначала ваш код не работал, получается, что моя версия cython не обновлялась. Что касается доступа к нему за пределами 'evalc',' cdef object name', то трюк для массива python и 'cdef inside_class inside_array [3 ] '. остается только выяснить, как сделать его переменным. Спасибо за вашу помощь! – MaMiFreak