Accessing void pointers in Python (using SWIG or something else)

大憨熊 提交于 2020-01-02 21:21:06

问题


I've been trying to use SWIG to wrap around a simple library that uses ioctl() to populate a structure like the following:

struct data
{
  header* hdr;
  void* data;
  size_t len;
};

data is a pointer to a buffer, len is the length of that buffer.

I'm unable to figure out how to convert data to a Python string (or array). Furthermore, I need a way to free that buffer in the destructor. Any suggestions are appreciated.


回答1:


Since you say "or something else" in the Q's title -- if you choose to use ctypes, you can represent a void* with c_void_p (one of ctypes' fundamental data types, and access functions such as free and memcpy from the C runtime library (as long as the latter's available as a DLL / .so dynamic library, but that's true pretty widely these days). To get a mutable character buffer into which you can memcpy the data, use create_string_buffer.

Of course you could alternatively use the Python C API -- PyByteArray_FromStringAndSize is what you'd use in this case to make a byte array copy from your void* and length (and of course you'd call free directly, when appropriate, since it's just C code anyway).

Another possibility to consider is Cython, a Python-like language designed to write Python extensions and such that the Cython compiler can generate compilable C code from Cython sources - in Cython, your struct would be:

cdef struct data:
    void* hdr
    void* data
    unsigned int* len

assuming you don't want to go to the trouble of declaring header (i.e., that only data and len matter to you here) -- size_t, I believe, is not part of Cython at this time (I could be wrong, they do keep adding stuff;-), but unsigned int can probably do.

Sorry, it's been too long since I used SWIG in earnest (what with all these excellent alternatives) -- I'd have skipped the Q were it not for that tempting "or something else" clause in the title;-).




回答2:


swig provides a module named 'cdata.i'. You should include this in the interface definition file.

Once you include this, it gives two functions cdata() and memmove(). Given a void * and the length of the binary data, cdata() converts it into a string type of the target language. memmove() is the reverse. given a string type, it will copy the contents of the string(including embedded null bytes) into the C void* type.

Handling binary data becomes much simple with this module. I hope this is what you need.



来源:https://stackoverflow.com/questions/2345354/accessing-void-pointers-in-python-using-swig-or-something-else

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