Вернуть указатель CTypes из C

Я пишу расширение Python C, которое должно возвращать указатель CTypes на массив char в памяти (мне нужно взаимодействовать с другой библиотекой Python, которая ожидает указатель CTypes).

Я не могу найти никакой документации по любому интерфейсу CTypes для C. Существуют ли какие-либо обходные пути, такие как вызов конструктора указателя 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? */
}

Заранее спасибо.


person Vicent Marti    schedule 28.12.2010    source источник
comment
Я что-то пропустил? Разве вы не просите: docs.python.org/library/ctypes.html #ctypes-указатели   -  person mjhm    schedule 28.12.2010
comment
Это код Python. Мне нужно построить указатель из C.   -  person Vicent Marti    schedule 28.12.2010
comment
Хотите использовать SWIG? Это так мощно~~~   -  person kaitian521    schedule 02.12.2011


Ответы (1)


Даже если вы программируете на C, попробуйте использовать сам Python. К сожалению, я не знаю какого-либо интерфейса CTypes для C и не смог найти подсказки в источниках. Возможно, вы сможете написать свой собственный метод 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 напрямую, возможно...

person tynn    schedule 04.01.2015