Прежде всего, я не понимаю, почему вы хотите возвращать указатель на функцию C из расширения Python только для вызова его из Python (через ctypes), тогда как логично было бы вызывать функцию C черезрасширение Python (если я что-то упустил).
Во-вторых, это не похоже, что ctypes вообще поддерживает PyCObject.Ваш вызов CFUNCTYPE (None, c_int) [я заменил c_void на None] с аргументом PyCObject, терпит неудачу, потому что CFUNCTYPE ожидает целое число и не знает, что делать с PyCObject.
Почему бы не написать оболочку Pythonвместо my_cfunc, который вы будете вызывать из Python без хлопот ctypes?Например:
PyObject *call_fptr(PyObject *self, PyObject *args)
{
int arg;
if (!PyArg_ParseTuple(args, "i", &arg))
return NULL;
my_cfunc(arg);
Py_RETURN_NONE;
}
В качестве бонуса, если вам нравится ctypes, обертку Python для my_func можно использовать для создания экземпляра внешней функции ctypes (в отличие от PyCObject)!
from ctypes import *
import foo
SOMEFUNC_T = CFUNCTYPE(None, c_int)
cfunc = SOMEFUNC_T(foo.call_fptr)
cfunc(1)
Редактировать: Указание, что функция C должна принимать переменное число аргументов, усложняет ваш вопрос ... Как бы вы все-таки обернули свою переменную функцию C-аргумента ctypes, учитывая, что CFUNCTYPE требует известного набораarguments?
Проблема в этом случае действительно сводится к преобразованию кортежа Python в список переменных аргументов в C, который, по-видимому, совсем не тривиален.Фактически SWIG посвятил этой проблеме раздел своей документации , например, так: Большинство других инструментов генерации оболочек мудро выбрали, чтобы избежать этой проблемы .
Тем не менее, он дает совет, что можно динамически создавать списки переменных аргументов в переносимой форме с помощью libffi .
Мое предложение, в конечном счете, заключается в том, чтобы обернуть вашу функцию переменных аргументов SWIG и избавь себя от боли.