Не работает с PyTCC , но в коде что-то не так.
Согласно [Python 3]: class ctypes. PyDLL ( имя, режим = DEFAULT_MODE, дескриптор = нет ) ( выделение - мое):
Экземпляры этогокласс ведет себя как CDLL экземпляры, за исключением того, что Python GIL не освобожден во время вызова функции, а после выполнения функции проверяется флаг ошибки Python.Если установлен флаг ошибки, возникает исключение Python.
Таким образом, это полезно только для непосредственного вызова API-функций Python C .
Примечание : CFUNCTYPE для CDLL , то же самое, что PYFUNCTYPE для PyDLL .
Как следствие, в pop_proto вы должны заменить ctypes.CFUNCTYPE
на ctypes.PyFUNCTYPE
(обратите внимание, что у вас есть опечатка в c_voidp ).
Далее на той же странице указано, что для PyObject * ( C ) следует использовать py_object ( Python ).Итак:
pop_proto = ctypes.PyFUNCTYPE(ctypes.py_object)
Если вы хотите быть строгим, вам придется включить аргументы в прототип, что сделает код более сложным, но для этого конкретного случая (они игнорируются), это не обязательно:
pop_proto = ctypes.PyFUNCTYPE(ctypes.py_object, ctypes.py_object, ctypes.py_object, ctypes.py_object)
Вот пример для PyObject *PyBytes_Repr(PyObject *obj, int smartquotes)
(вызывая функцию C по старинке):
[cfati@CFATI-5510-0:C:\WINDOWS\system32]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe"
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import sys
>>> import os
>>> import ctypes
>>>
>>> python_dll_name = os.path.join(os.path.dirname(sys.executable), "python" + str(sys.version_info.major) + str(sys.version_info.minor) + ".dll")
>>> python_dll_name
'e:\\Work\\Dev\\VEnvs\\py_064_03.07.03_test0\\Scripts\\python37.dll'
>>>
>>> python_dll = ctypes.PyDLL(python_dll_name)
>>>
>>> pybytes_repr_proto = ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.py_object, ctypes.c_int)
>>> pybytes_repr = pybytes_repr_proto(("PyBytes_Repr", python_dll))
>>>
>>> b = b"abcd"
>>>
>>> reprb = pybytes_repr(b, 0)
>>> reprb
"b'abcd'"
Вы также можете проверить [SO]: Как привести указатель ctypes к экземпляру класса Python (ответ @ CristiFati) .