How to read from pointer address in Python?

懵懂的女人 提交于 2020-04-16 02:52:09

问题


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?


回答1:


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.




回答2:


Once I got a pointer of memory location from C, I found "list(listSize * listDataType).from_address(memoryPointer)" created a internal copy of C memeory. If the data in memory is huge, Python takes a long time to create a list object by using internal copy. To avoid internal copy, I used the ctypelib.as_array in python:

import ctypes
import binascii
import numpy as np

myCfunslib.getData.restype = ctypes.c_void_p
#myCfunslib.getData.restype=ctypes.POINTER(ctypes.c_ubyte)#no need to cast
dataSize = 1092 * 1208
#call the c function to get the data memory pointer
cMemoryPointer = myCfunslib.getData();
newpnt = ctypes.cast(cMemoryPointer, ctypes.POINTER(ctypes.c_ubyte))
# and construct an array using this data
DataBytes = np.ctypeslib.as_array(newpnt, (dataSize,)) #no internal copy
print "the mid byte of the data in python side is ", DataBytes[dataSize/2]



回答3:


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])


来源:https://stackoverflow.com/questions/48808997/how-to-read-from-pointer-address-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!