I\'m sorry, but I generally have a hard time reading the current ctypes docs...
If I have a C function that takes a const char *
pointer, and I know
The type ctypes.c_char_p represents a nul-terminated string. If a function takes a const char* you can pass a Python string to it and it will receive a nul-terminated version.
A Windows example DLL:
#include <string.h>
__declspec(dllexport) char* func(char* a,size_t len,const char* b)
{
if(strlen(b) * 2 >= len)
return NULL;
strcpy_s(a,len,b);
strcat_s(a,len,b);
return a;
}
Python:
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> x=CDLL('x')
>>> x.func.restype=c_char_p
>>> x.func.argtypes=[c_char_p,c_int,c_char_p]
>>> s=create_string_buffer(10)
>>> x.func(s,len(s),'abcd')
'abcdabcd'
>>>
Assigning a new value to instances of the pointer types c_char_p, c_wchar_p, and c_void_p changes the memory location they point to, not the contents of the memory block (of course not, because Python strings are immutable):
>>> s = "Hello, World"
>>> c_s = c_char_p(s)
>>> print c_s
c_char_p('Hello, World')
>>> c_s.value = "Hi, there"
>>> print c_s
c_char_p('Hi, there')
>>> print s # first string is unchanged
Hello, World
>>>
You should be careful, however, not to pass them to functions expecting pointers to mutable memory. If you need mutable memory blocks, ctypes has a create_string_buffer function which creates these in various ways. The current memory block contents can be accessed (or changed) with the raw property, if you want to access it as NUL terminated string, use the string property:
Says the ctypes tutorial. What I gather from this is that only if the function would work with a const char*
, would passing in the python string be valid. Keep in mind, it won't have a null termination.
I'd suggest using create_string_buffer
anyhow.