Reputation: 69
Warning: I am pretty newbie with Cython. :D I have the following pieces of code:
my_structs.h:
typedef struct Dataset{
int lines;
char **tid;
}Dataset;
myiolib.pyx:
from libc.stdlib cimport malloc
from libc.string cimport strcpy
from cpython.string cimport PyString_AsString
cdef extern from "my_structs.h":
cdef struct Dataset:
int lines
char **tid
cdef Dataset readDataset(TID_name):
cdef:
int i, line_count=0
Dataset instance
with open(TID_name, 'rU') as file_iter:
for line in file_iter:
line_count=line_count+1
instance.tid = <char **>malloc(line_count * sizeof(char *))
i = 0
with open(TID_name, 'rU') as file_iter:
for line in file_iter:
instance.tid[i] = <char *>malloc((len(line)+1) * sizeof(char ))
strcpy(instance.tid[i], PyString_AsString(line.strip()))
i += 1
instance.lines = line_count
return instance
mytest.pyx:
import myiolib
cdef extern from "my_structs.h":
cdef struct Dataset:
int lines
char **tid
def test():
cdef Dataset D
D = myiolib.readDataset("test.dat")
# Do something...
# Free memory (?!)
test.py:
import mytest
mytest.test()
When I type: cython -a mytest.pyx it says: "Cannot convert Python object to 'Dataset' ", pointing at D = myiolib.readDataset("test.dat"). Why? I don't understand... What am I doing wrong?
Upvotes: 1
Views: 2791
Reputation: 60147
First, I think your minimal example is pretty bad. You don't include a setup.py
or any other way of running the code.
As such, here's a proper minimal example:
test_python.py
import pyximport
pyximport.install(setup_args={'include_dirs': "."})
import my_test
my_test.test()
my_test.pyx
import my_library
cdef extern from "my_type.h":
cdef struct MyType:
int x
def test():
cdef MyType my_instance
my_object = my_library.my_function()
my_library.pyx
cdef extern from "my_type.h":
cdef struct MyType:
int x
cdef MyType my_function():
return MyType()
my_type.h
typedef struct MyType {
int my_attribute;
} MyType;
This errors with:
AttributeError: 'module' object has no attribute 'my_function'
This is because cdef
is being used, so import
will not allow access to the function. You've used cdef
too, so I'm surprised this isn't happening with you. Maybe compiling with setup.py
doesn't require this; it wouldn't surprise me. Even then, though, you're using import
where you should be using cimport
.
Add a my_library.pxd
:
cdef extern from "my_type.h":
cdef struct MyType:
int x
cdef MyType my_function()
optionally remove cdef extern
from the pyx
file and change
import my_library
to
cimport my_library
and it works.
If these tips don't fix it for you, please give me an example I can run.
Upvotes: 1