Newbie, sending pointers from python to C

72 views
Skip to first unread message

Prashant Saxena

unread,
Apr 3, 2016, 1:31:33 AM4/3/16
to python-cffi
Hi,

Windows 7 x64
Python  2.7.11 x64
cffi 1.5.2
Microsoft python compiler for windows (vc++ 2008 x64)

I am trying my hands on cffi for the very first time. There is a C api in which most of functions has two parametes:


size_t arg_size,
const void *arg_value



Here we can pass either scalars or array. For this I have created a struct like this in cdef:

typedef struct {
   
void *data;
    size_t size
;
} buffer;

Now from python to pass data numpy array:
p =  ffi.cast("float *", data.ctypes.data)
buffer
= ffi.new("buffer *", [p, data.nbytes])
lib
.Test(buffer)
Test function goes like this:
void Test(buffer *data){
apiFunction
(data->size, data->data);
}
This is working fine as far as I am concerned for numpy based arrays and python integers,
but when I am passing float I am not able to receive it's value in C.
printf("%f\n", data->data)
actually prints 0.00000 but when I'm printing that float using:
printf("%d\n", data->data)
I am not receiving the decimal part. For e.g. if float is 462.236, it's only printing 462. I have no idea what's
going on. In general I am looking for a solution that could work in given scenario.

Cheers
Prashant









Damien Ruiz

unread,
Apr 4, 2016, 11:54:02 AM4/4/16
to python-cffi
Hi Prashant,

You cannot print a float using %d in C, because %d only prints integer, and the integer part of 462.236 is 462.

What happens when you try to print 462.236 with %f?

Prashant Saxena

unread,
Apr 4, 2016, 10:51:18 PM4/4/16
to python-cffi
Hi Damien,

When I'm printing float, it's printing 0.00000. There is one more thing I came to know about numpy.
It's behaving inconsistently when using numpy.float32 data type. Yesterday night out of sudden numpy.float32
became C double and today morning It's working fine.

Right now the only solution I have is to use single element numpy array for scalars.
scalar = numpy.array(1, dtype=numpy.int32)
This works fine.



Adam Gradzki

unread,
Apr 5, 2016, 9:36:09 AM4/5/16
to pytho...@googlegroups.com
Make sure your Numpy array is C-contiguous.
You can check this with ndarray flag: C_CONTIGUOUS
And convert it using:

--
-- python-cffi: To unsubscribe from this group, send email to python-cffi...@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/python-cffi?hl=en
---
You received this message because you are subscribed to the Google Groups "python-cffi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-cffi...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Adam G

unread,
Apr 5, 2016, 9:48:16 AM4/5/16
to python-cffi
Prashant,

I have some demo code using cffi, numpy, and float * you can take a look at for inspiration:

Adam Gradzki

unread,
Apr 5, 2016, 10:12:51 AM4/5/16
to pytho...@googlegroups.com
Now that I am revisiting this code I am not sure if I have found a bug in CFFI or if it is in my own code.

git checkout 8c27abe535554f5aac5bcc4e96ea9185b8a804bd
If you run `python3 -O imgsample.py` then the tests will complete without error.
However, the same code run without -O will fail! Unexplainable.
cffi==1.5.2, numpy==1.10.4, cc==Apple LLVM version 7.3.0 (clang-703.0.29)

Additionally, I found the behavior of ffi.from_buffer(my_input) to be buggy, and my code worked again when I replaced this piece of code with my_input.ctypes.data. 
Here is the diff that fixed things:



Armin Rigo

unread,
Apr 6, 2016, 12:23:51 AM4/6/16
to pytho...@googlegroups.com
Hi,

On 3 April 2016 at 08:31, Prashant Saxena <anima...@gmail.com> wrote:
>
>
> I am trying my hands on cffi for the very first time. There is a C api in which most of functions has two parametes:
>
> size_t arg_size,
> const void *arg_value

I am not sure to understand why, if you have a function which takes
these two arguments, you cannot directly call the C function with two
corresponding arguments. Why do you need the intermediate ``typedef
struct { void*; size_t;} buffer;``?

> Now from python to pass data numpy array:
> p = ffi.cast("float *", data.ctypes.data)
> buffer = ffi.new("buffer *", [p, data.nbytes])
> lib.Test(buffer)

You can do directly

lib.apiFunction(data.nbytes, ffi.cast("float *", data.ctypes.data))

> This is working fine as far as I am concerned for numpy based arrays and python integers,
> but when I am passing float I am not able to receive it's value in C.
> printf("%f\n", data->data)
> actually prints 0.00000 but when I'm printing that float using:
> printf("%d\n", data->data)
> I am not receiving the decimal part.

This sounds like a C problem. ``data->data`` is a pointer, right?
When you use ``%f`` to print a pointer, you get nonsense. When you
use ``%d`` to print a pointer, I would expect that you get nonsense as
well. I don't know why you get the integer part of some float number.
Are you sure you use exactly the line above, with the ``data->data``
field being a pointer?


A bientôt,

Armin.
Reply all
Reply to author
Forward
0 new messages