How to read from pointer address in Python?

前端 未结 3 1670
南方客
南方客 2021-01-20 19:27

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 give

相关标签:
3条回答
  • 2021-01-20 20:02

    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]
    
    0 讨论(0)
  • 2021-01-20 20:07

    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])
    
    0 讨论(0)
  • 2021-01-20 20:12

    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.

    0 讨论(0)
提交回复
热议问题