对不起,但我通常很难阅读当前的ctypes文档...
如果我有一个带有const char *
指针的C函数,并且我知道它既不会修改传入的字符串,也不会在函数调用之外保留对它的引用,它将指针直接传递给python字符串的字节真的很有意义。
ctypes可以做到这一点还是只是普通的不支持?我真的必须create_string_buffer
并将我的字符串复制到其中吗?
答案 0 :(得分:15)
为指针类型实例分配新值c_char_p,c_wchar_p和c_void_p会更改它们指向的内存位置,而不是内存块的内容(当然不会,因为Python字符串是不可变的):
>>> 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
>>>
但是,你应该小心,不要 将它们传递给期待的功能 指向可变内存的指针。如果你 需要可变的内存块,ctypes有 一个create_string_buffer函数 以各种方式创造这些。该 当前内存块的内容可以 使用原始访问(或更改) 属性,如果你想访问它 NUL终止字符串,使用字符串 属性:
说ctypes教程。我从中收集的是,只有当函数与const char*
一起使用时,传入python字符串才有效。请记住,它不会有空终止。
无论如何,我建议使用create_string_buffer
。
答案 1 :(得分:4)
类型ctypes.c_char_p表示以空字符结尾的字符串。如果一个函数接受一个const char *,你可以将Python字符串传递给它,它将收到一个以nul结尾的版本。
Windows示例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'
>>>