1. Python CFFI
  2. Untitled project
  3. cffi
Issue #79 new

no translation from Python2 "str" to C "const char*" in a struct field

Zooko O'Whielacronx
created an issue

Folks:

Thank you for CFFI!

I have a struct defined like this:

typedef struct { size_t len; char* buf; } zstr;

and I pass instance of this struct by value in C, like this:

double unigram_prob_1(const zstr unigram, Pvoid_t* pUP);

CFFI is supposed to know what to do if I pass a Python "str" as an argument where a C "const char*" is required, and it is supposed to know what to do if I pass a Python tuple where a C struct is required, but putting the two together it does not know what to do if I pass Python2 "(len(mystr), mystr)" as the first argument to unigram_prob_1(). Is this a bug, or by-design? Thanks!

(It would be great for me if it would do what I want here. I'm currently rewriting all my C code to take two arguments -- len and buf -- wherever it used to take a zstr, and this is a hassle.)

Comments (2)

  1. Armin Rigo

    It's a bug I suppose. The reason is that ffi.new("zstr *", [len(mystr), mystr]) does not work, and that's correct. There is a special case only for function arguments to receive a "char[]" instead of a "char *", and thus a string is acceptable. But a "zstr" is a "zstr", and so the standard rules apply. While I see the point, I'm a bit unsure how exactly to fix it.

  2. Armin Rigo

    Trying to think more about this problem. If we allow recursively to give Python objects that are transformed into pointers and structs for the call, it raises an interesting question: should the following example work, or fail with a recursion error?

    ffi.cdef("""
        struct node { struct node *next; };
        void f(struct node);
    """)
    
    my_node = {}
    my_node['next'] = [my_node]   # circular pointer
    lib.f(my_node)
    
  3. Log in to comment