2

I would like to get a file object for a block of memory in Python 2.5 under Windows.(for some reasons I cannot use newer versions for this tasks.)

So as input I do have a pointer and a size and let's assume that I need only read only access.

In case you'll wonder, I got these by using ctypes and I need to make them available to a function that expects a filehandler (read-only).

I considered using cStringIO but in order to create such an object I need a string object.

4
  • you have a pointer ?? what does a pointer mean in python ? Commented Nov 18, 2011 at 10:46
  • 1
    meanss the same thing as in C - an in process memory address where your data is. How to get to said data is a whole different problem. Commented Nov 18, 2011 at 10:59
  • Added details, as requested :) Commented Nov 18, 2011 at 11:03
  • beware that a python fileobject is a python only construct: it does not always have system file handle associated with it. Commented Nov 18, 2011 at 11:19

2 Answers 2

6

You should use ctypes in there. As of Python 2.5 ctypes where already on the standard library, so a "win" situation for you.

With ctypes you can construct a python object representing a higher level pointe doing this:

import ctypes 
integer_pointer_type = ctypes.POINTER(ctypes.c_int)
my_pointer = integer_pointer_type.from_address(your_address)

You can then address the memory contents as a Python indexed object, like print my_pointer[0]

This won't give you a "file like interface" - although it would be trivial to wrap a class with a "read" and "seek" methods around such an object:

class MyMemoryFile(object):
    def __init__(self, pointer, size=None):
         integer_pointer_type = ctypes.POINTER(ctypes.c_uchar)
         self.pointer = integer_pointer_type.from_address(your_address)
         self.cursor = 0
         self.size = size

    def seek(self, position, whence=0):
         if whence == 0:
              self.cursor = position
         raise NotImplementedError
    def read(size=None):
         if size is None:
             res =  str(self.pointer[cursor:self.size])
             self.cursor = self.size
         else:
             res = str(self.pointer[self.cursor:self.cursor + size]
             self.cursor += size
         return res

(not tested - write me if it does not work - can be fixed)

Please note that attempts to read the memory beyond the space allocated for your data structure will have the exact same effects as doing so in C: in most cases,a segmentation fault.

Sign up to request clarification or add additional context in comments.

1 Comment

I didn't test it as well, but I think that giving a read size greater than self.size is bad. Better check it. And maybe put the self.cursor stuff immendiately before the return res, in the form of self.cursor += len(res) - this covers all cases.
1

from the ctypes documentation, it appears that you can get a string from an address in memory, using the ctypes.string_at() function.

the problem is that a string is not mutable, that means that you won't be able to modify the resulting string from python. to have a mutable buffer in python, you will need to call the ctypes.create_string_buffer() function from python.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.