Write buffer in C which is allocated in python using ctypes, and read back again in python

Amit Sharma

Problem Statement:

Allocate one buffer of given size 16*100 using numpy array in python, and fill that buffer in C with some struct content, and then wanted to read back that buffer in python again.

I have one struct defined as follows:

sample.c

    #include <stdio.h>

    typedef unsigned char           uint8_t;
    typedef short                   int16_t;
    typedef unsigned short          uint16_t;

    struct S{
        int a;
    };

    struct ins_data {
        int16_t offset1;
        int16_t num1;
        int16_t offset2;
        int16_t num2;
        void *buffer;  //==> Need to fill this buffer with struct S contents
    };

    struct desc_data {
        uint8_t id;
        void *ins_data;
    };

    void access_ins_data(struct ins_data* ptr) {
        int i = 0;

        struct S *p = (struct S*)ptr->buffer;
        printf("offset1: %d\n", ptr->offset1);
        ptr->offset1 = 12;
        ptr->num1 = 13;

        struct S tt;
        tt.a = 10;

        memcpy(p, &tt, sizeof(struct S));

        /* Want to fill this buffer in below fashion, but its not even working for single case.
         * |struct S s1|struct S s2| struct S s3|
         *
         */
        printf("S.a: %d\n", p->a);
    }

    void printLib() {
        printf("Oh Yeah.. you are here");
    }

    void foo(void *p) {
        struct desc_data *ptr = (struct desc_data*)p;
        printf("id: %d\n", ptr->id);
        access_ins_data(ptr->ins_data);
        struct ins_data *ss = (struct ins_data *)ptr->ins_data;
        struct S *pp = (struct S*)ss->buffer;
        printf("foo : %d\n", pp->a);
    }

Command used to generate .so file: gcc -o sample.so -shared -fPIC sample.c

And below is the code for python world:

samplePython.py

    from ctypes import *
    import numpy as np

    class S(Structure):
        pass
    S._fields_ = [
        ('a', c_int32),
    ]

    class ins_data(Structure):
        pass
    int16_t = c_int16
    ins_data._fields_ = [
        ('offset1', int16_t),
        ('num1', int16_t),
        ('offset2', int16_t),
        ('num2', int16_t),
        ('buffer', c_void_p),
    ]

    class desc_data(Structure):
        pass
    uint8_t = c_uint8
    desc_data._fields_ = [
        ('id', uint8_t),
        ('ins_data', c_void_p),
    ]

    def get_ins_data():
        arr = np.zeros(16*100, dtype='uint8')
        enc_data = ins_data(-1,0,-1,0)
        enc_data.buffer = cast(np.ctypeslib.as_ctypes(arr), c_void_p)

        return enc_data

    from ctypes import cdll
    newA = cdll.LoadLibrary("sample.so")

    foo = newA.foo
    foo.argtypes = [c_void_p]
    foo.restype = None

    insData = get_ins_data()
    descData = desc_data(0, cast(byref(insData), c_void_p))
    foo(cast(byref(descData), c_void_p))

    print "descData.id", descData.id
    tt= cast(descData.ins_data, POINTER(ins_data))
    buff = cast(tt[0].buffer, POINTER(S))
    print "buffer content", buff.contents.a

Output:

id: 0
offset1: -1
S.a: 10
foo : 10
descData.id:  0
buffer content 1140653488 #This should come 10?

Problem:

buffer content showing garbage value. It should show 10.

Thanks in advance, badly stuck in this simple code. :(

benjarobin

Here the conversion of the C code (main function):

from ctypes import *
import numpy as np

class S(Structure):
    _fields_ = [
        ('a', c_int32)
    ]

class ins_data(Structure):
    _fields_ = [
        ('offset1', c_int16),
        ('num1', c_int16),
        ('offset2', c_int16),
        ('num2', c_int16),
        ('buffer', c_void_p)
    ]

class desc_data(Structure):
    _fields_ = [
        ('id', c_uint8),
        ('ins_data', c_void_p)
    ]


from ctypes import cdll
newA = cdll.LoadLibrary("./sample.so")

foo = newA.foo
foo.argtypes = [c_void_p]
foo.restype = None


A = create_string_buffer(16 * 100)
dData = desc_data()
iData = ins_data()

dData.id = 1

iData.offset1 = -1
iData.num1 = 0
iData.offset2 = -1
iData.num2 = 0
iData.buffer = cast(A, c_void_p)

dData.ins_data = cast(pointer(iData), c_void_p)
foo(byref(dData))

pp = cast(dData.ins_data, POINTER(ins_data))
p = cast(pp.contents.buffer, POINTER(S))

print("@@@@: {}".format(p[0].a))
print("@@@@: {}".format(p[1].a))
print("@@@@: {}".format(p[2].a))

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to pass a python list to C function (dll) using ctypes

From Dev

Export C++ function to python using ctypes: undefined symbol

From Dev

Loading dll using Python Ctypes

From Dev

Python `ctypes` - How to copy buffer returned by C function into a bytearray

From Dev

Returning a C array from a C function to Python using ctypes

From Dev

python: ctypes, read POINTER(c_char) in python

From Dev

How can I read and write to the serial buffer in the same Python script?

From Dev

How to write to a temporary file in Python and read from it again?

From Dev

creating a python module using ctypes

From Dev

How to create a C struct from Python using ctypes?

From Dev

Python packet sniffer using ctypes crashes when copying socket buffer

From Dev

ctypes using HRESULT(python)

From Dev

Pass a cython allocated buffer to python

From Dev

How to pass the StringBuilder parameter in C# to ctypes in python, which is not the normal ctypes supported datatype

From Dev

Passing a python list to "c" DLL function which returns array data using ctypes

From Dev

ctypes from buffer - Python

From Dev

Python ctypes writing data to be read by C executable

From Dev

Python ctypes passing string pointer / buffer

From Dev

Converting binary to string, then back again using python

From Dev

Python ctypes pointer and allocated memory

From Dev

Interrupting a Python C-extension with Ctrl-C using ctypes

From Dev

How can I read back from a buffer using ctypes?

From Dev

python ctypes how to write string to given buffer

From Dev

Python to .cpp and back again with ctypes via an .so

From Dev

Python print() corrupting memory allocated by ctypes

From Dev

Python Ctypes - String to c_char_p to c_void_p and back

From Dev

Python using os and chdir to read and write to iCloud

From Dev

How can I get the same object back (pass by reference) when calling C++ code from Python (using ctypes)?

From Dev

Serial read & write using Arduino and Python

Related Related

  1. 1

    How to pass a python list to C function (dll) using ctypes

  2. 2

    Export C++ function to python using ctypes: undefined symbol

  3. 3

    Loading dll using Python Ctypes

  4. 4

    Python `ctypes` - How to copy buffer returned by C function into a bytearray

  5. 5

    Returning a C array from a C function to Python using ctypes

  6. 6

    python: ctypes, read POINTER(c_char) in python

  7. 7

    How can I read and write to the serial buffer in the same Python script?

  8. 8

    How to write to a temporary file in Python and read from it again?

  9. 9

    creating a python module using ctypes

  10. 10

    How to create a C struct from Python using ctypes?

  11. 11

    Python packet sniffer using ctypes crashes when copying socket buffer

  12. 12

    ctypes using HRESULT(python)

  13. 13

    Pass a cython allocated buffer to python

  14. 14

    How to pass the StringBuilder parameter in C# to ctypes in python, which is not the normal ctypes supported datatype

  15. 15

    Passing a python list to "c" DLL function which returns array data using ctypes

  16. 16

    ctypes from buffer - Python

  17. 17

    Python ctypes writing data to be read by C executable

  18. 18

    Python ctypes passing string pointer / buffer

  19. 19

    Converting binary to string, then back again using python

  20. 20

    Python ctypes pointer and allocated memory

  21. 21

    Interrupting a Python C-extension with Ctrl-C using ctypes

  22. 22

    How can I read back from a buffer using ctypes?

  23. 23

    python ctypes how to write string to given buffer

  24. 24

    Python to .cpp and back again with ctypes via an .so

  25. 25

    Python print() corrupting memory allocated by ctypes

  26. 26

    Python Ctypes - String to c_char_p to c_void_p and back

  27. 27

    Python using os and chdir to read and write to iCloud

  28. 28

    How can I get the same object back (pass by reference) when calling C++ code from Python (using ctypes)?

  29. 29

    Serial read & write using Arduino and Python

HotTag

Archive