当前位置: 首页 > 面试题库 >

通过cython从c调用python代码

穆博简
2023-03-14
问题内容

所以我想通过cython从c调用一些python代码。我设法从c调用cython代码。而且我还可以从cython调用python代码。但是,当我将它们全部加在一起时,会丢失一些东西。

这是我的python代码(quacker.pyx):

def quack():
    print "Quack!"

这是我的cython“ bridge”(caller.pyx):

from quacker import quack

cdef public void call_quack():
    quack()

这是c代码(main.c):

#include <Python.h>
#include "caller.h"

int main() {
  Py_Initialize();
  initcaller();
  call_quack();
  Py_Finalize();
  return 0;
}

运行此命令时,出现以下异常:

Exception NameError: "name 'quack' is not defined" in 'caller.call_quack' ignored

我怀疑缺少的部分:

  • 我还没打电话 initquacker()
  • 我还没有 quacker.h
  • Cython没有产生任何东西quacker.h-only quacker.c
  • caller.c不导入quacker.h或调用initquacker()

我不太确定是否有可能做我想做的事情,但是在我看来应该做到。我很想听听您可能有任何意见。

编辑:

这就是我进行cythonize /编译/链接/运行的方式:

$ cython *.pyx
$ cc -c *.c -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
$ cc -L/System/Library/Frameworks/Python.framework/Versions/2.7/lib -L/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -lpython2.7 -ldl *.o -o main
$ ./main

问题答案:

如果将重命名quacker.pyxquacker.py,则实际上一切正确。唯一的问题是您的程序将不会在当前目录中搜索python模块,从而导致输出:

Exception NameError: "name 'quack' is not defined" in 'caller.call_quack' ignored

但是,如果将当前目录添加到PYTHONPATH环境变量,则输出将成为您期望的输出:

$ PYTHONPATH=".:$PYTHONPATH" ./main 
Quack!

在运行python shell时,根据文档,当前目录(或包含脚本的目录)会sys.path自动添加到变量中,但是使用创建一个简单程序Py_InitializePy_Finalize似乎不会发生。由于PYTHONPATH变量也用于填充sys.pathpython变量,因此上述解决方法会产生正确的结果。

另外,在该Py_Intialize行下方,您可以sys.path通过执行一些指定为字符串的python代码,向空字符串添加如下:

PyRun_SimpleString("import sys\nsys.path.insert(0,'')");

重新编译后,只需运行即可./main

编辑

如果您按照问题中指定的方式运行代码,那么看看正在发生的事情实际上很有趣,因此无需重命名quacker.pyx文件。在那种情况下,该initcaller()函数尝试导入quacker模块,但是由于不存在quacker.py或不quacker.pyc存在,因此无法找到该模块,并且该initcaller()函数会产生错误。

现在,通过引发异常以Python方式报告此错误。但是main.c文件中的代码不会对此进行检查。我不是专家,但是在我的测试中,添加下面的代码initcaller()似乎可行:

if (PyErr_Occurred())
{
    PyErr_Print();
    return -1;
}

程序的输出将变为以下内容:

Traceback (most recent call last):
  File "caller.pyx", line 1, in init caller (caller.c:836)
    from quacker import quack
ImportError: No module named quacker

通过调用 beforeinitquacker()函数,模块名称已被注册,因此在内部完成的import调用将检测到它已被加载,并且调用将成功。
__initcaller()``quacker``initcaller()



 类似资料:
  • 我想 用 C 语言编写一个求和列表的函数,名为 sum_list.c 将 文件设为 sum_list.so 它在步骤4中引发错误: ctypes。ArgumentError:参数1::不知道如何转换参数1 当我用c编写一个函数,将两个数字相加时,它可以正常工作。 所以,重点是我不知道怎么把一个list (python对象)传递给c。 sum_list.c python代码 我希望我的 python

  • 13.4. 通过cgo调用C代码 Go程序可能会遇到要访问C语言的某些硬件驱动函数的场景,或者是从一个C++语言实现的嵌入式数据库查询记录的场景,或者是使用Fortran语言实现的一些线性代数库的场景。C语言作为一个通用语言,很多库会选择提供一个C兼容的API,然后用其他不同的编程语言实现(译者:Go语言需要也应该拥抱这些巨大的代码遗产)。 在本节中,我们将构建一个简易的数据压缩程序,使用了一个G

  • 本文向大家介绍cython 包装DLL:从C ++到Cython到Python,包括了cython 包装DLL:从C ++到Cython到Python的使用技巧和注意事项,需要的朋友参考一下 示例 这展示了一个用Cython包装C ++ dll的简单例子。它将涵盖以下主要步骤: 使用Visual Studio使用C ++创建示例DLL。 用Cython包裹DLL,以便可以在Python中调用它。

  • 问题内容: 现在,我已经在Windows 7上成功安装了Cython,我尝试使用Cython编译一些Cython代码,但是gcc使我的生活变得艰难。 使用gcc编译代码时,会抛出数十个 对 -erros的 未定义引用 ,并且我很确定src是可用的(如安装教程所述,如果缺少此文件,则会抛出 对 -errors的 未定义引用 )。 奇怪的是,使用*或-script可以很好地工作,但是当仍然在模块上工作

  • 问题 你想使用Cython来创建一个Python扩展模块,用来包装某个已存在的C函数库。 解决方案 使用Cython构建一个扩展模块看上去很手写扩展有些类似, 因为你需要创建很多包装函数。不过,跟前面不同的是,你不需要在C语言中做这些——代码看上去更像是Python。 作为准备,假设本章介绍部分的示例代码已经被编译到某个叫 libsample 的C函数库中了。 首先创建一个名叫 csample.p

  • 问题内容: 构建与C或C ++库的Python绑定的最快方法是什么? (如果这很重要,我正在使用Windows。) 问题答案: Boost Python库是用于连接Python和C 的框架。它使您可以快速而无缝地将C 类的函数和对象暴露给Python,反之亦然,而无需使用特殊工具-仅使用C 编译器即可。它被设计为以非介入方式包装C 接口,因此您不必为了包装而完全更改C ++代码,从而使Boost.