casting into a Python string from a char[] returned by a DLL

25,875

Solution 1

ctypes.cast() is used to convert one ctype instance to another ctype datatype. You don't need it To convert it to python string. Just use ".value" to get it in python string.

>>> s = "Hello, World"
>>> c_s = c_char_p(s)
>>> print c_s
c_char_p('Hello, World')
>>> print c_s.value
Hello, World

More info here

Solution 2

If you set the argtypes or restype attributes of ctypes functions, they will return the right Python object without the need for a cast.

Here's an example calling the C-runtime time and ctime functions:

>>> from ctypes import *
>>> m=CDLL('msvcrt')
>>> t=c_long(0)
>>> m.time(byref(t))
1326700130
>>> m.ctime(byref(t))  # restype not set
6952984
>>> m.ctime.restype=c_char_p  # set restype correctly
>>> m.ctime(byref(t))
'Sun Jan 15 23:48:50 2012\n'
Share:
25,875
Peter Li
Author by

Peter Li

Updated on January 16, 2020

Comments

  • Peter Li
    Peter Li over 4 years

    I am attempting to cast a C style const char[] string pointer (returned from a DLL) into a Python compatible string type. but when Python27 executes:

    import ctypes
    
    charPtr = ctypes.cast( "HiThere", ctypes.c_char_p )
    print( "charPtr = ", charPtr )
    

    we get: charPtr = c_char_p('HiThere')

    perhaps something is not to be evaluating properly. My questions are:

    1. how should one cast this charPtr back into a Python compatible, print-able string?
    2. is the cast operation just mentioned doing what it should be doing?
  • Mark Tolonen
    Mark Tolonen about 7 years
    @HelinWang no, it doesn't. In this case ctime returns a pointer to static memory so there is nothing to manage.
  • Helin Wang
    Helin Wang about 7 years
    Do you know about the general case? : c library returned a memory allocated on the heap.
  • Mark Tolonen
    Mark Tolonen about 7 years
    @HelinWang Even in the general case, if C allocates it, C must free it. In that case you don't want to use c_char_p either, because ctypes is "helpful" and converts it to a Python string. You don't get the returned pointer so can't pass it to a ctypes-wrapped free function. Use another type such as POINTER(char) or c_void_p, extract the string, then pass the pointer to free or the like.