Santiago Aguiar wrote:
> I've started to use Cython just yesterday, and I'm facing some 
> difficulties ;). I'm sorry to ask this on the dev list, but I didn't 
> found a user specific one...
> 
> I have a struct-dense C source code that defines the PDU of a network 
> protocol and functions to read/write from a buffer struct.
> 
> First, I don't know if I'm doing this the right way, but I had to define 
> by hand all my structs again on Cython to use them. I think it's the way 
> to do it, but I did feel like repeating myself over and over ;).

That's the way to do it, though. You only go through that once for each
struct you use (and your code that uses the struct is likely longer than
the struct itself), so it's not too much work.

Note that you do not need to declare the complete struct. Just write down
the fields you need. Cython doesn't need to know the others and the C
compiler sees the struct anyway. That also allows you to ignore any
externally referenced complex types that you do not use yourself.


> Second, at this extremely un-proficient time, for each of the structs on 
> my pdu.pyx I have something like this:
> 
> cdef class Msg1(Message):
>     cdef public ... (one declaration for each field present in the struct)

Why don't you reference the struct itself here? Do you really need these
fields to be public? Some methods for setting up common use cases are often
a lot better than just having users set everything by hand, especially when
there are non-trivial type conversions involved, or when there are
interdependencies between fields that are better checked for validity. For
example, Cython cannot check arbitrary integer values for you that the user
writes into an enum type attribute.


>     def __init__(self, ... (one keyword parameter for each field 
> provided by the struct):
>        self.fieldN = ... (this repeated for every field)
>     cdef void from_c(self, msg1_c_struct *msg1):
>        self.fieldN = msg1.fieldN (repeated for every field, with some 
> additional mappings in case the field is a struct)

There is some special support for struct assignments from dicts, you can
try that. I have no idea where that's documented, though. Robert?


> And then I have a message parser that uses the C functions to read the 
> PDU and wrap it on Msg1:
> 
> class Parser:
>     def read_pdu(self, str_data):
>        cdef msg_struct msg
>        ....
>        pdu_read(data, &msg)
>        ....
>        if msg.header.type == MSG_1_TYPE:
>           return Msg1().from_c(&msg.data.msg_1)
> 
> Where msg.data.msg_1 is of type msg1_c_struct.
> 
> On that code, I get an error message saying that: 'Cannot convert 
> 'msg1_c_struct *' to Python object' where I do the Msg1().from_c.

You have to assign the result of Msg1() to a typed variable. Otherwise,
Cython doesn't know that the thing it returns is really of type Msg1 (and
not a generic Python object) and that it does have a C typed from_c() method.


> I don't understand why I'm getting the error. If I call a cdef function 
> instead of a cdef method, it works OK; but shouldn't I be able to call a 
> cdef method and passing a C type instead of a Python type? Otherwise, I 
> will need to add an external cdef function for each class to create the 
> object from the struct... I must be doing something wrong :).

I consider this a deficiency of Cython. It should know the type of the
result when you call an extension type.

http://trac.cython.org/cython_trac/ticket/232

Stefan

_______________________________________________
Cython-dev mailing list
Cython-dev@codespeak.net
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to