Skip to main content
 首页 » 编程设计

python之从 C 返回 CTypes 指针

2025年05月04日13jiqing9006

我正在编写一个 Python C 扩展,它需要将 CTypes 指针返回到内存中的 char 数组(我需要与另一个需要 CTypes 指针的 Python 库进行交互)。

我找不到关于 C 的任何类型的 CTypes 接口(interface)的任何文档。是否有任何解决方法,例如调用 Python 指针构造函数?

static PyObject *get_pointer(myObject *self) 
{ 
    char *my_pointer = self->internal_pointer; 
    return PyCTypes_Pointer(my_pointer); /* how do I turn 'my_pointer' into  
              a Python object representing a CTypes pointer? */ 
} 

提前致谢。

请您参考如下方法:

即使您使用 C 编程,也请尝试使用 Python 本身。可悲的是,我不知道 C 的任何类型的 CTypes 接口(interface),也无法在源代码中找到任何提示。也许您可以使用以下代码编写自己的 PyCTypes_Pointer 方法。

我没有在这里做任何清理、错误检查或处理,但它正在为我使用 Python 2.7 和 3.4。

#include <Python.h> 
 
static const char *test = "Testing Python ctypes char pointer ...";  
 
static PyObject *c_char_p = NULL; 
static PyObject *c_void_p = NULL; 
static PyObject *cast = NULL; 
 
static PyObject * char_p ( void ) { 
    PyObject *p = PyLong_FromVoidPtr((void *) test); 
    p = PyObject_CallFunction(c_void_p, "O", p); 
    return PyObject_CallFunction(cast, "OO", p, c_char_p); 
} 
 
static PyObject *len ( void ) { 
    return PyLong_FromSize_t(strlen(test)); 
} 
 
static PyMethodDef methods[] = { 
    {"char_p", (PyCFunction) char_p, METH_NOARGS, ""}, 
    {"len", (PyCFunction) len, METH_NOARGS, ""}, 
    { NULL } 
}; 
 
#if PY_MAJOR_VERSION >= 3 
static PyModuleDef module = {PyModuleDef_HEAD_INIT, "pyt", "", -1, methods, 
    NULL, NULL, NULL, NULL}; 
#define INIT_FUNC PyInit_pyp 
#else 
#define INIT_FUNC initpyp 
#endif 
 
PyMODINIT_FUNC INIT_FUNC ( void ) { 
    PyObject* m; 
 
    PyObject *ctypes = PyImport_ImportModule("ctypes"); 
    PyObject *c_char = PyObject_GetAttrString(ctypes, "c_char"); 
    c_char_p = PyObject_CallMethod(ctypes, "POINTER", "O", c_char); 
    c_void_p = PyObject_GetAttrString(ctypes, "c_void_p"); 
    cast = PyObject_GetAttrString(ctypes, "cast"); 
 
#if PY_MAJOR_VERSION >= 3 
    m = PyModule_Create(&module); 
#else 
    m = Py_InitModule("pyp", methods); 
#endif 
 
    return (PyMODINIT_FUNC) m; 
} 

只需构建

from __future__ import print_function 
from distutils.core import Extension, setup 
import sys 
sys.argv.extend(["build_ext", "-i"]) 
setup(ext_modules = [Extension('pyp', ['pyp.c'])]) 
import pyp 
c = pyp.char_p() 
print(c[:pyp.len()]) 

并得到类似的输出

<class 'ctypes.LP_c_char'> Testing Python ctypes char pointer ... 

如果您只处理以零结尾的字符串,您可以直接使用 ctypes.c_char_p,也许...