1

出于研究原因,我正在尝试将 C 和 Python 结合起来,但我的代码中遇到了问题。我使用了教程中的代码,但似乎获取 python 文件的代码不起作用。这是代码:

你好类.py

def sayHello(name):
return "Hello " + name + "!"

主程序

int main(int argc, const char * argv[]) {
char name[50];
printf("What's your name?\n");
fgets(name, 64, stdin);
char *answer = NULL;
PyObject *modname, *mod, *mdict, *func, *stringarg, *args, *rslt;
Py_Initialize();
PySys_SetPath(Py_GetPath()); 
modname = PyString_FromString("helloClass");
mod = PyImport_Import(modname);// Here mod = null because it can´t find it.
if (mod){
    mdict = PyModule_GetDict(mod);
    func = PyDict_GetItemString(mdict, "sayHello");
    if (func){
        if (PyCallable_Check(func)) {
            stringarg = PyString_FromString(name);
            args = PyTuple_New(1);
            PyTuple_SetItem(args, 0, stringarg);
            rslt = PyObject_CallObject(func, args);
            if (rslt) {
                answer = PyString_AsString(rslt);
                Py_XDECREF(rslt);
            }
            Py_XDECREF(stringarg);
            Py_XDECREF(args);
        }
        Py_XDECREF(mdict);
        Py_XDECREF(func);
    }
    Py_XDECREF(modname);
    Py_XDECREF(mod);
}
printf("%s", answer);
answer = NULL; }
4

1 回答 1

1

这里没有足够的信息给你完整的答案,但基本问题几乎可以肯定是helloClass.py它不会在模块搜索路径的任何地方结束,所以PyImport_Import找不到它。

例如,也许您正在将main可执行文件构建到类似的位置~/Library/Developer/Xcode/DerivedData/Hello/Build/Products/Release/hello,但不在那里复制helloClass.py。或者,也许您正在将其复制到那里,但等效的dirname $0不在您的模块路径中。或者……嗯,有一百万种可能性,但在每种情况下答案都是一样的:

  1. 找出可执行文件和 Python 文件的安装位置。

  2. 从这些知识中建立一条适当的(可能是相对的)路径。

  3. 确保该路径被添加到模块路径中。

关于 Python 如何搜索模块的确切细节在不同版本之间有所不同,但基本思想在The importstatement(或3.3 版本,它遵循导入系统)中进行了解释,并且通常只是在sys.path.

(请注意,如果您正在构建 .app 包而不仅仅是 Unix 命令行可执行文件,则有一个标准答案——您将 .py 文件放在标准位置,使用 Cocoa 或 CoreFoundation API 获取路径,并且然后使用它。但这似乎与这里无关。)


查看您在https://github.com/Eduardof0nt/help.git上传的项目:

你不是helloClass.py在任何地方复制。您必须决定要将它复制到哪里,这完全取决于您要如何部署事物。但是出于调试目的,只是为了获得可测试的东西,您可以将它放在Hello Python!可执行文件旁边(inbuild/Debugbuild/Release)。要做到这一点:

  • 在项目导航器中选择项目。
  • 在出现的项目视图的左侧栏中选择目标。
  • 选择构建阶段选项卡。
  • 单击添加构建阶段按钮。
  • 添加复制文件阶段。
  • 将其目标设置为产品目录。
  • helloClass.py从 Project Navigator 拖入构建阶段。

现在,当您构建时,如果您查看输出(打开“All”和“All Messages”),您将在“Link build/Debug/Hello Python”之后看到“Copy build/Debug/helloClass.py” !”。而且,如果您查看该目录内部,您会并排看到这两个文件。

但这并不能解决您的全部问题。因为/wherever/you/started/build/Debug不会出现在sys.pathPython 使用的那个上。解决此问题的最快方法是在Py_SetProgramName(argv[0])之前Py_Initialize()PySys_SetArgvEx(argc, argv, 1)之后调用。对于您的用例,这可能不是正确的做法,但是您将阅读文档并了解所有这些内容,因为我无法解释在 SO 中嵌入 Python 的所有细节回答。

当您尝试学习这些东西时,您可能想要进行一些调试。例如,您可以printf(path=%s\n", Py_GetPath())查看sys.path等价物是什么,以及PyObject_Print(mod, stdout, 0)查看 中的内容mod等等。但实际上,您会想要使用 Xcode 调试器——添加断点并尝试在运行时执行这些操作。

大部分内容在 Python 解释器的扩展和嵌入中进行了解释,您确实需要阅读它;没有替代品。(您不需要阅读整个Python/C API 参考手册,但在完成之前,您最终会阅读大量内容,并擅长搜索它。)但是,因为嵌入 Python 的次数要少得多比扩展它更常见,文档实际上并不包含您需要的所有内容,所以……如果您使用的任何教程都没有涵盖诸如PySys_*and之类的内容Py_GetPath,您可能需要先找到一个更好的教程。

于 2013-02-19T21:22:07.227 回答