是否可以通过ctypes引用传递python字符串?

por*_*uod 5 python ctypes

对不起,我通常很难阅读当前的ctypes文档...

如果我有一个带有const char *指针的C函数,并且我知道它既不会修改传入的字符串,也不会在函数调用之外保留对它的引用,那么将指针直接传递给python的字节真的很有意义串.

ctypes可以做到这一点,还是只是简单的不支持?我真的必须create_string_buffer将我的字符串复制到其中吗?

小智 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
>>>
Run Code Online (Sandbox Code Playgroud)

但是,您应该小心,不要将它们传递给期望指向可变内存的函数.如果你需要可变内存块,ctypes有一个create_string_buffer函数,它以各种方式创建它们.可以使用raw属性访问(或更改)当前内存块的内容,如果要以NUL终止字符串的形式访问它,请使用string属性:

说ctypes教程.我从中收集到的是,只有当函数与a一起工作时const char*,传入python字符串才有效.请记住,它不会有空终止.

create_string_buffer无论如何,我建议使用.


Mar*_*nen 5

类型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;
}
Run Code Online (Sandbox Code Playgroud)

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'
>>>
Run Code Online (Sandbox Code Playgroud)

  • Python 文档说...“无、整数、长整型、字节字符串和 unicode 字符串是唯一可以直接用作这些函数调用中的参数的本机 Python 对象。...字节字符串和 unicode 字符串作为指向包含其数据(char * 或 wchar_t *)的内存块。” ...在[调用函数](http://docs.python.org/2/library/ctypes.html#calling-functions)部分,就在[基本数据类型](http://docs.python .org/2/library/ctypes.html#fundamental-data-types) (2认同)