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:
#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:
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
id: 0
offset1: -1
S.a: 10
foo : 10
descData.id: 0
buffer content 1140653488 #This should come 10?
buffer content showing garbage value. It should show 10.
Thanks in advance, badly stuck in this simple code. :(
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.
Comments