No se puede llamar al método de extensión de Python C
-
04-10-2019 - |
Pregunta
Estoy trabajando en hacer mi primera extensión de Python C, que define un par de funciones y tipos personalizados. Lo extraño es que los tipos personalizados están trabajando, pero no las funciones regulares. Los archivos de nivel superior MyModule.c es similar al siguiente:
static PyMethodDef MyModule_methods[] = {
{"doStuff", MyModule_doStuff, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
static struct PyModuleDef MyModule_module = {
PyModuleDef_HEAD_INIT,
"mymodule",
"Documentation",
-1,
MyModule_methods
};
PyMODINIT_FUNC PyInit_audioDevice(void) {
PyObject *object = PyModule_Create(&MyModule_module);
if(object == NULL) {
return NULL;
}
if(PyType_Ready(&MyCustomType_type) < 0) {
return NULL;
}
Py_INCREF(&MyCustomType_type);
PyModule_AddObject(object, "MyCustomType", (PyObject*)&MyCustomType_type);
return object;
}
Estoy construyendo la extensión con este archivo setup.py:
from distutils.core import setup, Extension
setup(name = "mymodule",
version = "1.0",
ext_modules = [Extension("mymodule", ["MyModule.c", "MyCustomType.c", "DoStuff.c"])])
El archivo "DoStuff" define su función como tal:
static PyObject*
AudioOutputOSX_doStuff(PyObject *self, PyObject *args) {
printf("Hello from doStuff\n");
return Py_None;
}
Lo curioso es que el tipo MyCustomType funciona bien, ya que puedo crear una instancia con:
from mymodule.MyCustomType import MyCustomType
foo = MyCustomType()
Y veo mi printf () declaraciones de nuevos métodos e init del tipo de encargo impreso. Sin embargo, este código falla:
import mymodule
mymodule.doStuff()
Me sale el siguiente error: Rastreo (llamadas recientes más última): Archivo "MyModuleTest.py", línea 9, en mymodule.doStuff (tampón) AttributeError: 'módulo' objeto no tiene atributo 'hacerTarea'
¿Qué está pasando aquí? ¿Tengo algún error en declaraciones de métodos de mi módulo de alguna manera?
Solución
El hecho de que este código funciona:
from mymodule.MyCustomType import MyCustomType
Es absolutamente sorprendente y nos dice que es en realidad un mymodule
paquete , y MyCustomType
un módulo dentro de ese paquete (que contiene un tipo o clase con el mismo nombre).
Por lo tanto, llamar a la función, usted obviamente tiene que ver:
from mymodule import MyCustomType as therealmodule
therealmodule.doStuff()
o similar -. Asumiendo que la información que usted nos da, sobre todo la primera línea de código que he citado de código que decir obras, es de hecho exacta ??p>
Otros consejos
¿Qué ves si lo hace import mymodule
seguido por print(dir(mymodule))
?
Es el módulo realmente lo suficientemente grande como para ser dividido en 3 archivos? La división se le añade una gran cantidad de complejidad con el nombre de vinculación ...-mangling, tal vez?
AudioOutputOSX_doStuff
frente MyModule_doStuff
... un verdadero problema, o simplemente un problema de preguntas edición?
¿En qué plataforma, lo compilador?