I am a newbiew to python and ctypes. what I have is:-
C program:
struct query
{
uint16_t req_no;
uint32_t req_len;
uint64_t req;
};
struct response
{
uint16_t req_no;
uint16_t status;
uint32_t value_len;
uint64_t value;
};
// functions for creating query and response packets using
// above structs respectively, returning char buffer.
char* create_query(//some args);
char* create_response(//some args);
I have Created a libquery.so for the above C code. My TCP Server is a C program. I am trying to create a TCP python client (my project needs it!) for the same.
I can successfully send query and receive data(using functions in libquery.so) from python client. But when i get response data, I want to convert it to "struct response" type. I have create a similar "Structure" class in python, but can't get anything out of it.
Please help.
Some code snippet of my Python code:-
// some ctypes imports
lib = cdll.LoadLibrary('./libquery.so')
class Info1(Structure):
_fields_ = [("req_no",c_int),
("status",c_int),
("value_len",c_int),
("value",c_int)]
header = Info1()
// Did some TCP connection code here and send data to server by calling
// create_query() method, data confirmed to be correct on server side...
# Receive response data
data = sock.recv(512)
header = str_to_class('Info1')
header.req_no = int(ord(data[0])) // Works; but I don't want to go this ways..
header.status = int(ord(data[1]))
header.value_len = int(ord(data[2]))
header.value = int(ord(data[3]))
print above header values..
I tried using :-
def str_to_class(Info1):
return getattr(sys.modules[__name__], Info1)
But don't know how to make it work.
Anybody know how to make it work OR is there any other way??
Your 'Info1' does not match C 'struct response'. So I changed in following code. You can use ctypes.memmove .
from ctypes import *
class Info1(Structure):
_fields_ = [("req_no", c_uint16),
("status", c_uint16),
("value_len", c_uint32),
("value", c_uint64)]
data = (
'\x01\x00'
'\x02\x00'
'\x03\x00\x00\x00'
'\x04\x00\x00\x00\x00\x00\x00\x00'
)
# Assumed data was received. I assumed both server, clients are little-endian.
# else, use socket.ntoh{s|l}, socket.hton{s|l} ....
header = Info1()
memmove(addressof(header), data, sizeof(header))
assert header.req_no == 1
assert header.status == 2
assert header.value_len == 3
assert header.value == 4
You can also use struct .
import struct
data = '....' # same as above
struct.unpack('HHLQ', data) == (1, 2, 3, 4) # '>HHLQ' if data is htonl/htons-ed in sencding part.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.