出于研究的原因,我试图将C和Python结合起来,但是我的代码中出现了问题。我使用了教程中的代码,但似乎获取python文件的代码不起作用。代码如下:
地狱杯.py

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

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

最佳答案

这里没有足够的信息来给出完整的答案,但基本的问题几乎可以肯定的是helloClass.py不会在模块搜索路径上的任何地方结束,因此PyImport_Import找不到它。
例如,您可能正在将main可执行文件构建到类似于~/Library/Developer/Xcode/DerivedData/Hello/Build/Products/Release/hello的位置,但没有在那里复制helloClass.py。或者,您可能正在复制它,但模块路径上没有等效的dirname $0。或者……好吧,有一百万种可能性,但答案在任何情况下都是一样的:
找出可执行文件和Python文件的安装位置。
从这些知识中建立一条合适的(可能是相对的)路径。
确保将路径添加到模块路径。
Python如何搜索模块的具体细节在不同版本之间是不同的,但是基本思想在The importstatement中解释过(或者the 3.3 version,它遵从于The import system),而且通常只是在sys.path中添加一些内容。
(请注意,如果您构建的是.app bundle,而不是Unix命令行可执行文件,则有一个标准答案:将.py文件放在标准位置,使用Cocoa或CoreFoundation api获取路径,然后使用该路径。但这似乎与此无关。)
查看您在https://github.com/Eduardof0nt/help.git上传的项目:
你不能在任何地方复制。你必须决定复制到哪里,这完全取决于你想如何部署。但出于调试的目的,为了获得可测试的东西,您可以将它放在helloClass.py可执行文件旁边(在Hello Python!build/Debug中)。要做到这一点:
在项目导航器中选择项目。
在显示的项目视图的左侧栏中选择目标。
选择构建阶段选项卡。
单击“添加生成阶段”按钮。
添加复制文件阶段。
将其目标设置为产品目录。
build/Release从项目导航器拖到构建阶段。
现在,当您构建时,如果您查看输出(打开“All”和“All Messages”),您将在“Link build/Debug/Hello Python!”后面看到“Copy build/Debug/helloClass.py!”。而且,如果您查看该目录,您将看到两个文件并排排列。
但这并不能解决你的全部问题。因为helloClass.py不会出现在Python使用的/wherever/you/started/build/Debug上。最快的方法是在sys.path之前和Py_SetProgramName(argv[0])之后调用Py_Initialize()。对于您的用例来说,这可能不是正确的做法,但是您将阅读文档并理解所有这些操作的作用,因为我不可能解释在SO答案中嵌入Python的所有细节。
当你试图学习这些东西时,你可能想做一些调试。例如,您可以PySys_SetArgvEx(argc, argv, 1)查看printf(path=%s\n", Py_GetPath())等价物是什么,以及sys.path查看PyObject_Print(mod, stdout, 0)中的内容,等等。但实际上,您需要使用Xcode调试器添加一个断点,并在运行时尝试执行这些操作。
这在Extending and Emnbedding the Python Interpreter中有很多解释,您确实需要阅读它;没有替代品。(您不需要阅读整个Python/C API Reference Manual,但在完成之前,您最终将阅读大量的内容,并能够很好地搜索它。)然而,由于嵌入Python比扩展Python更不常见,因此文档实际上并不包含您所需的所有内容,因此…如果您正在使用的任何教程都不包括modPySys_*之类的内容,您可能会首先需要找到一个更好的教程。

07-26 06:39
查看更多