Reputation: 1044
i would like to convert a python object to cython structure by doing as i did bellow, but it doesn't assigns the values of simres[1] to the resulta[x].cpt1
cdef struct resultaStructure:
double score
char **cpt1
simRes = [1.0,
['http://bioontology.org/projects/ontologies/fma/fmaOwlDlComponent_2_0#Abdomen',
'Abdomen']]
cdef x = 0
cdef resultaStructure *resulta = <resultaStructure *> malloc(sizeof(resultaStructure)*labelsSourceTaille)
resulta[x].score = simRes[0]
print("score : ",resulta[0].score)
resulta[x].cpt1 = <char**> malloc (sizeof (char**)*2)
print('2')
resulta[x].cpt1[0] = <char*> malloc (sizeof (char)*simRes[1][0].__len__()+1)
print('3')
resulta[x].cpt1[1] = <char*> malloc (sizeof (char)*simRes[1][1].__len__()+1)
print('4')
resulta[x].cpt1[0] = <char*> simRes[1][0]
print('5')
resulta[x].cpt1[1] = <char*> simRes[1][1]
print('6')
print("cpt1 0 : ",resulta[0].cpt1[0])
print("cpt1 1 : ",resulta[0].cpt1[1])
here is the result
('score :', 1.0)
2
3
4
Upvotes: 4
Views: 928
Reputation: 30888
The code in the question and in OP's answer has serious issues which will likely cause the program to crash in the long term.
resulta[x].cpt1 = <char**> malloc (sizeof (char**)*2)
cpt1
is a pointer to (an array of) char pointers. Thus it should be assigned as
resulta[x].cpt1 = <char*> malloc (sizeof (char*)*2)
(Better yet, if the length is always 2
then assign char *cpt1[2]
in the struct definition and you don't need to malloc
it.)
This is unlikely to cause a real problem since all pointers are the same size but it's still wrong.
resulta[x].cpt1[0] = <char*> malloc (sizeof (char)*simRes[1][0].__len__()+1)
# ...
resulta[x].cpt1[0] = <char*>some_python_string
Here you allocate some memory, the promptly forget about the memory you've allocated if favour of making the pointer point at a different area of memory owned by the Python string. What you don't do is copy data from the Python string into your allocated memory.
str1 = simRes[1][0].encode('UTF-8')
resulta[x].cpt1[0] = <char*> str1
The memory that cpt1[0]
points to is owned by str1
. If str1
gets freed before you've finished using your structure then the structure points to invalid memory and your program will crash, or read some random data that's allocated later, or some other bad thing.
If you can guarantee that str1
will outlive your structure (for example, your structure is used as an argument for one C function call) then this is OK, but in the general case it probably isn't.
The solution is to copy the contents or str1
into your newly allocated memory:
resulta[x].cpt1[0] = <char*> malloc (sizeof (char)*len(simRes[1][0])+1)
strcpy(resulta[x].cpt1[0],str1)
(Also, You are remembering to free
all the memory you've malloc
ed, right?)
Upvotes: 2
Reputation: 1044
the solution is by encoding the python string before assignment as follow ,
str1 = simRes[1][0].encode('UTF-8')
resulta[x].cpt1[0] = <char*> str1
print('5')
str2 = simRes[1][1].encode('UTF-8')
resulta[x].cpt1[1] = <char*> str2
Upvotes: 1