Is it possible to pass a python string by reference via ctypes?

Sorry, but I usually find it difficult to read the current ctypes docs ...

If I have a C function that takes a const char * pointer, and I know that it will not change the changed string and will not refer to it outside the function call, it really makes sense to pass the pointer directly to the bytes of the python string.

Can ctypes do this or is it just not supported? Do I really have to create_string_buffer and copy my string into it?

+4
source share
2 answers

Assigning a new value to instances of pointer types c_char_p, c_wchar_p, and c_void_p changes the location of the memory they are pointing to, and not the contents of the memory block (of course not, since 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 must be careful, however, do not pass them to functions that expect pointers to mutable memory. if you need modified blocks of memory, ctypes has a create_string_buffer function that creates them in different ways. the current contents of the memory block can be accessed (or changed) with an unprocessed property, if you want to access it as a NUL terminated string, use the line Property:

Says the ctypes tutorial. I understood from this that only if the function works with const char* , a python string will be passed. Keep in mind that it will not have zero completion.

I would suggest using create_string_buffer anyway.

+13
source

The ctypes.c_char_p type represents a zero-terminated string. If the function accepts const char *, you can pass it a Python string and it will get a version with zero completion.

Example DLL for Windows:

 #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' >>> 
+4
source

Source: https://habr.com/ru/post/1347045/


All Articles