How to read from pointer address in Python?


How to read from pointer address in Python?



I want to read in a Python script a number of bytes starting from a specific address. E.g., I want to read 40000 bytes starting from 0x561124456.



The pointer is given from a C# app. I want to use this method to pass data between the app and script. I've used a TCP socket via localhost, but I want to try this method also.



How can I do this?





Why do you want to do this? Python does not have pointers. What is responsible for putting those bytes at that address in the first place?
– Daniel Roseman
Feb 15 at 13:57






@DanielRoseman I've updated the question.
– Cristian M
Feb 15 at 14:02





I wonder if ctypes.<some c type>.from_address would be useful here? Having just tried it twice, I got OverflowError and a hard crash with no exception, but maybe there's some way to avoid those.
– Kevin
Feb 15 at 14:03


ctypes.<some c type>.from_address


OverflowError





Yeah, putting data into a memory location isn't a good way of passing between applications. That is what sockets are for.
– Daniel Roseman
Feb 15 at 14:55





@DanielRoseman Why isn't it a good way? I can make the the buffer fixed, so it isn't deallocated and I pass the pointer to the script. I think this method is faster than using a socket through localhost whose performance is limited by the CPU and TCP/IP stack performance.
– Cristian M
Feb 16 at 6:13




2 Answers
2



If you really want to, enjoy:


import ctypes
g = (ctypes.c_char*40000).from_address(0x561124456)



Looks like segfault fun. There are good socket-connection libraries on both languages (sockets, RPC etc...), so I would think about this again if this is for some large project.



I happened to work on the similar issue. My python script load .so library to get an image buffer address from c++ .so. After I got the buffer address, I need to be able to read each byte in the buffer. I used "from_address" to create a list object:


imageBytes = list(c_ubyte * dataSize).from_address(pointer)



The following shows the details how to get memory address passed from c++ to pyth and how to access the memory data on python side too. In c++ code frameprovider.cpp:


dataPackPtr = new DataPack();

DataPack * getFrame(){
uint32_t width = 1920;
uint32_t height = 1208;
const size_t buffersize = width * height * 4;//rgba, each color is one byte
unsigned char* rgbaImage = (unsigned char * )malloc(buffersize);
memset(rgbaImage, 0, buffersize); // set all the buffer data to 0.
dataPackPtr->width = width;
dataPackPtr->height = height;
dataPackPtr->buffersize = buffersize;
dataPackPtr->bufferPtr = rgbaImage;
return dataPackPtr;
}

extern "C" {
DataPack* getFrame_wrapper(){
return getFrame();
}
}



My python:


import ctypes
import binascii
lib = ctypes.cdll.LoadLibrary('/libpath/frameprovider.so')
print vars(lib)

class dataPack(ctypes.Structure):
_fields_ = [("width",ctypes.c_int),
("height",ctypes.c_int),
("buffersize",ctypes.c_int),
("bufferAddress", ctypes.c_void_p)]

lib.getFrame_wrapper.restype = ctypes.POINTER(dataPack)
data = lib.getFrame_wrapper()
print "in python the w= ", data.contents.width, "h=",data.contents.height
print "the buffersize=",data.contents.height
imageBytes = list(
(data.contents.buffersize * ctypes.c_ubyte).
from_address(data.contents.bufferAddress))

print "the len of imageBytes are ", len(imageBytes)
print imageBytes[data.contents.buffersize -1] #print the last byte in the buffer
print "in python, the hex value of element 12 is ", hex(imageBytes[12])






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift