【问题标题】:Unable to import Python module written in C无法导入用 C 编写的 Python 模块
【发布时间】:2017-08-14 17:40:58
【问题描述】:

我一直在尝试研究如何从 C 脚本(没有 swig 或除 MinGW 之外的任何其他东西)制作 .pyd(Python 扩展模块)文件,并已成功将其构建为 .pyd

但是当我尝试导入模块时会出现问题。

如果我运行它,模块会成功运行(据我所知),然后会出现一个错误提示 Python Has Stopped Working,它会关闭而不执行程序的其余部分。

这是我的 C 脚本 (test.c):

#include <python.h>

int main()
{
    PyInit_test();
    return 0;
}

int PyInit_test()
{
    printf("hello world");
}

和 Python 脚本(file.py):

import test
print('Run From Python Extension')

我编译了脚本:

gcc -c file.py
gcc -shared -o test.pyd test.c

在命令提示符下编译并使用 python 3.6(在 Windows 10 上运行)时,我找不到任何错误。

我在这个主题上找不到太多信息,我更愿意远离 Cython(我已经知道 C)和 Swig。

任何帮助告诉我出了什么问题都会很棒。

【问题讨论】:

  • .pyd 文件是否与尝试import 的 Python 脚本位于同一文件夹中? Python 在某些位置以定义的方式搜索模块,可能只是您的库不在它看起来的任何地方。请参阅文档中的Building C and C++ Extensions
  • 你的模块初始化函数没有做任何初始化模块的尝试。它甚至没有正确的返回类型。你读过文档吗?
  • @martineau 我将.pyd 放在与我尝试从中导入它的python 脚本相同的文件夹中。这让我开始思考,然后我把它放在了 Lib 中。从这里我可以导入它而不会出现错误但是'hello world'并没有打印'finished'

标签: python c python-c-api pyd


【解决方案1】:

创建 Python 扩展与编写常规 C 代码完全不同。您所做的只是创建了一个有效的 C 程序,但这对 Python 没有意义。

这就是你的程序应该是什么样子(它只是一个骨架,而不是正确的工作代码):

#include <Python.h>
#include <stdlib.h>

static PyObject* test(PyObject* self, PyObject* args)
{
    printf("hello world");
    return NULL;
}

static PyMethodDef test_methods[] = {
    {"test", test, METH_VARARGS, "My test method."},
    {NULL, NULL, 0, NULL} /* Sentinel */
};

PyMODINIT_FUNC init_test_methods() {
    Py_InitModule("test", test_methods);
}

int main(int argc, char** argv)
{
    /* Pass argv[0] to the Python interpreter */
    Py_SetProgramName(argv[0]);

    /* Initialize the Python interpreter. Required. */
    Py_Initialize();

    /* Add a static module */
    init_test_methods();
}

我建议您通过以下链接了解更多信息:http://dan.iel.fm/posts/python-c-extensions/ 以及 official docs

【讨论】:

  • 这很有意义。谢谢您的帮助。正如你所说的不同,编译怎么样,还是我必须做一些不同的事情来编译它(设置脚本)?
  • 编译没有什么秘密。如果您愿意,请查看我的这个项目,其中我用 C 语言实现了凯撒密码并为其提供了 Python 扩展:github.com/matheusportela/caesar-cipher
  • 这对编译问题进行了排序,并为我提供了一个很好的学习示例。至于编译是setup.py build,不是我之前说的。再次感谢¦]
  • 最后一点:setup.py build 不断生成错误消息 unable to find vcvarsall.bat 我最后使用了-c mingw32 标志。这给出了另一个错误Unknown MS Compiler version 1900 which was solved here,它终于编译了。
  • 太好了,@西蒙!因为我通常不在 Windows 中编程,所以我没有意识到这个问题。很高兴知道你想通了。
猜你喜欢
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-27
  • 2023-02-26
  • 2015-03-09
  • 1970-01-01
相关资源
最近更新 更多