无法在Python C扩展中调用方法

0 投票
2 回答
746 浏览
提问于 2025-04-16 04:28

我正在制作我的第一个Python C扩展,这个扩展定义了一些函数和自定义类型。奇怪的是,自定义类型可以正常工作,但普通函数却不行。最上面的MyModule.c文件看起来是这样的:

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;
}

我用这个setup.py文件来构建扩展:

from distutils.core import setup, Extension
setup(name = "mymodule",
      version = "1.0",
      ext_modules = [Extension("mymodule", ["MyModule.c", "MyCustomType.c", "DoStuff.c"])])

在“DoStuff”文件中,它是这样定义函数的:

static PyObject*
AudioOutputOSX_doStuff(PyObject *self, PyObject *args) {
  printf("Hello from doStuff\n");
  return Py_None;
}

有趣的是,MyCustomType类型工作得很好,我可以这样实例化它:

from mymodule.MyCustomType import MyCustomType
foo = MyCustomType()

而且我能看到自定义类型的new和init方法中的printf()语句被打印出来。然而,这段代码却失败了:

import mymodule
mymodule.doStuff()

我得到了以下错误信息: Traceback (most recent call last): File "MyModuleTest.py", line 9, in mymodule.doStuff(buffer) AttributeError: 'module' object has no attribute 'doStuff'

这到底是怎么回事?我的模块方法声明是不是哪里出错了?

2 个回答

0

如果你输入 import mymodule 然后再输入 print(dir(mymodule)),你会看到什么呢?

你的模块真的大到需要分成三个文件吗?分开文件会让事情变得复杂,比如链接的问题... 可能还会有名字混淆的问题?

AudioOutputOSX_doStuffMyModule_doStuff 之间的区别... 这是个真正的问题,还是只是编辑问题?

你在什么平台上,使用什么编译器?

2

这段代码能够正常运行,

from mymodule.MyCustomType import MyCustomType

真是让人惊讶,这说明 mymodule 实际上是一个,而 MyCustomType 是这个包里面的一个模块(它包含了一个同名的类型或类)。

所以,要调用这个函数,你显然需要这样做:

from mymodule import MyCustomType as therealmodule
therealmodule.doStuff()

或者类似的方式——前提是你给我们的信息,特别是我引用的那行代码,确实是准确的。

撰写回答