Impossibile chiamare il metodo in estensione Python C
-
04-10-2019 - |
Domanda
Sto lavorando per rendere la mia prima estensione Python C, che definisce alcune funzioni e tipi personalizzati. La cosa strana è che i tipi personalizzati stanno lavorando, ma non le funzioni regolari. Gli sguardi dei file di livello superiore MyModule.c come questo:
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;
}
Sto costruendo l'estensione con questo file setup.py:
from distutils.core import setup, Extension
setup(name = "mymodule",
version = "1.0",
ext_modules = [Extension("mymodule", ["MyModule.c", "MyCustomType.c", "DoStuff.c"])])
Il file "DoStuff" definisce la sua funzione in quanto tale:
static PyObject*
AudioOutputOSX_doStuff(PyObject *self, PyObject *args) {
printf("Hello from doStuff\n");
return Py_None;
}
La cosa divertente è che il tipo di MyCustomType funziona bene, come posso istanziare con:
from mymodule.MyCustomType import MyCustomType
foo = MyCustomType()
E vedo il mio printf () le dichiarazioni di metodi nuovi e init del tipo personalizzato stampati. Tuttavia, questo codice non riesce:
import mymodule
mymodule.doStuff()
ottengo il seguente errore: Traceback (chiamata più recente scorso): File "MyModuleTest.py", linea 9, in mymodule.doStuff (buffer) AttributeError: oggetto 'modulo' non ha alcun attributo 'doStuff'
Che cosa sta succedendo qui? Devo qualche errore di dichiarazioni di metodo di mio modulo in qualche modo?
Soluzione
Il fatto che questo codice funziona:
from mymodule.MyCustomType import MyCustomType
è assolutamente sorprendente e ci dice che mymodule
è in realtà un pacchetto , e MyCustomType
un modulo all'interno di quel pacchetto (che contiene un tipo o classe con lo stesso nome).
Quindi, per chiamare la funzione, avrete, ovviamente, ha a che fare:
from mymodule import MyCustomType as therealmodule
therealmodule.doStuff()
o simili -. Assumendo le informazioni che ci date, in particolare quella prima riga di codice che ho citato dal codice che dice lavori, è infatti esatto
Altri suggerimenti
Che cosa si vede se si fa import mymodule
seguito da print(dir(mymodule))
?
è il modulo in realtà abbastanza grande da essere divisa in 3 file? Splitting aggiunge un bel po 'di complessità con il collegamento ... nome-mangling, forse?
AudioOutputOSX_doStuff
contro MyModule_doStuff
... un vero problema, o solo un problema di domanda-editing?
Quale piattaforma, cosa compilatore?