Je suis un débutant à Cython avec un peu de connaissances en C et une certaine expérience python. Actuellement, j'essaie de connaître les types étendus, mais je ne comprends pas ce qui se passe avec les valeurs de pointeurs dans l'exemple suivant (code ci-dessous l'explication).pointeurs comme attributs dans les types étendus cython
En tant qu'exercice, j'implémente un solveur factice. Le problème est représenté par deux nombres 'a' et 'b' et la solution par 's', où s = a * b. J'ai défini deux structures C correspondantes, problem
et solution
. La structure du problème a deux membres int, 'a' et 'b'; la structure de la solution a un membre 's'. Il y a une fonction pour initialiser la structure du problème, init_problem(problem *p,int a, int b)
. En outre, il existe une fonction qui prend des pointeurs vers les structures et renvoie une solution, solution solve(problem *p)
. Enfin, deux autres fonctions impriment les valeurs (void dump_problem(problem *p)
et void dump_solution(solution *s)
). Tout cela en utilisant les déclarations cdef
.
Ensuite, j'utilisé trois façons d'exposer le code C à python: fonction def
do_things(int a,int b)
qui enveloppe les fonctions C, et deux cdef class
, un en utilisant struct comme attributs et l'autre à l'aide des pointeurs vers structs comme des attributs (Solver_s
et Solver_p
, respectivement), y compris les méthodes d'emballage pour imprimer le problème et les solutions. La classe Solver_s fonctionne comme prévu. cependant, lors de l'utilisation de Solver_p, les pointeurs ne semblent pas être initialisés, renvoyant des valeurs incorrectes (voir test_pointers et sections de sortie). Je suppose que je manque un point sur les pointeurs et leur portée, mais je ne peux pas comprendre ce qui se passe. Toute aide pour obtenir ceci est grandement appréciée. J'utilise python 3.5.3 et cython 0.25.2 dans OS X 10.11.6 (El Capitan)
P.S: Première fois demander à SO, donc si je ne suis pas clair, je serai heureux de clarifier!
pointers.pyx
from libc.stdio cimport printf
cdef struct problem:
int a
int b
cdef struct solution:
int s
cdef void init_problem(problem *p,int a, int b):
p.a = a
p.b = b
cdef solution solve(problem *p):
cdef solution s
s.s = p.a * p.b
return(s)
cdef void dump_problem(problem *p):
printf("Problem dump: a = %d,b = %d\n",p.a,p.b)
cdef void dump_solution(solution *s):
printf("Solution dump: s= %d\n",s.s)
def do_things(int a,int b):
cdef problem p
init_problem(&p,a,b)
cdef solution s = solve(&p)
dump_problem(&p)
dump_solution(&s)
cdef class Solver_s: #Structs as attributes of Solver
cdef problem p
cdef solution s
def __cinit__(self,int a,int b):
print("\tInside Solver_s __cinit__")
init_problem(&self.p,a,b)
dump_problem(&self.p)
self.s = solve(&self.p)
dump_solution(&self.s)
print("\tGetting out of Solver_s __cinit__")
def show_problem(self):
dump_problem(&self.p)
def show_solution(self):
dump_solution(&self.s)
cdef class Solver_p: #Pointers to structs as attributes
cdef problem *pptr
cdef solution *sptr
def __cinit__(self,int a, int b):
print("\tInside Solver_p __cinit__")
cdef problem p
self.pptr = &p
cdef solution s
self.sptr = &s
init_problem(self.pptr,a,b)
dump_problem(self.pptr) #It shows right values
self.sptr[0] = solve(self.pptr)
dump_solution(self.sptr) #It shows right values
print("\tGetting out of Solver_p __cinit__")
def show_problem(self):
dump_problem(self.pptr)
def show_solution(self):
dump_solution(self.sptr)
test_pointers.py
import pyximport; pyximport.install()
import pointers
print("\tSolving as a function")
pointers.do_things(2,3)
print("\tSolving as a Extended Type, structs as attributes")
sol_s = pointers.Solver_s(4,5)
print("\t###Problem definition unsing Solver_s methods###")
sol_s.show_problem()
print("\t###Solution definition using Solver_s methods###")
sol_s.show_solution()
print("\tSolving as a Extended Type, pointers to structs as attributes")
sol_p = pointers.Solver_p(6,7)
print("\t###Problem definition unsing Solver_p methods###")
print("\t###Gives weird values###")
sol_p.show_problem()
print("\t###Solution definition using Solver_p methods###")
print("\t###Gives weird values###")
sol_p.show_solution()
Sortie
Solving as a function
Problem dump: a = 2,b = 3
Solution dump: s= 6
Solving as a Extended Type, structs as attributes
Inside Solver_s __cinit__
Problem dump: a = 4,b = 5
Solution dump: s= 20
Getting out of Solver_s __cinit__
###Problem definition unsing Solver_s methods###
Problem dump: a = 4,b = 5
###Solution definition using Solver_s methods###
Solution dump: s= 20
Solving as a Extended Type, pointers to structs as attributes
Inside Solver_p __cinit__
Problem dump: a = 6,b = 7
Solution dump: s= 42
Getting out of Solver_p __cinit__
###Problem definition unsing Solver_p methods###
###Gives weird values###
Problem dump: a = 1,b = 0
###Solution definition using Solver_p methods###
###Gives weird values###
Solution dump: s= 185295816