Cython - 共享Cython模块

时间:2017-05-03 15:59:44

标签: c++ cython

我有cython模块base.pyx和derived.pyx。 base.pyx及其导入定义base.pxd文件已定义,并使用derived.pyxcimport文件中使用。这些文件放置在here

在Python应用程序中使用cython生成的共享对象时,模块已正确导入,但在Cpp应用程序中使用库时,始终会出现ImportError: No module named 'base'错误。

我还在我的Cpp应用程序中添加了当前路径

  PyObject* path = PySys_GetObject("path");
  PyObject* result = PyObject_CallMethod(path,"append","(s)",".");
  Py_XDECREF(result);

即使这样,应用程序也看不到cython模块。请让我知道这种路径不匹配的原因是什么。

1 个答案:

答案 0 :(得分:5)

此处的一些混淆是关于cimport的行为 - OP试图使用derived.pyx编辑cimport的文件base.pyx,并试图通过C ++。

cimport做了两件事:

  1. 它允许Cython知道在另一个cdef.pyx文件中定义的.pxd函数,以便它可以访问这些函数。这发生在编译时。
  2. import那个模块。这在运行时发生,可以通过检查生成的C代码来查看。 import是" import蚂蚁"有两个原因:

    1. base.pyx中使用的函数可能需要在base中初始化全局变量或类,这在导入时完成。

    2. 它会导致base共享对象物理加载到内存中,并将derived中的某些函数指针初始化为cdef中的base函数

    3. 请注意,import并未真正将base添加到derived的模块字典中,因此它并不完全相同一个Python导入。

      我认为OP的一部分令人困惑的是import

      第二个问题仅在提问时显示,因为它涉及一个未写在问题中的关键细节。我设法让代码按照提供的方式工作:

      python3 setup.py build_ext --inplace
      g++ test.cpp -o test `python3-config --libs --includes` ./derived.cpython-36m-x86_64-linux-gnu.so
      ./test
      

      (其中第二行可能需要更改以匹配已编译的派生模块的确切名称)。 @PierredeBuyl做了一些稍微不同的事情,但同样发现代码没有任何变化。

      问题实际上是OP正在将derived.cpython-36m-x86_64-linux-gnu.sobase.cpython-36m-x86_64-linux-gnu.so重命名为libderived.solibbase.so。对于与derived程序直接关联的test,这并不是一个问题,但这意味着Python导入机制无法找到base(因为它已重命名)。

      作为社区维基发布,让自己与尽可能多的声誉脱离关系,因为我认为这是一个共同努力的事情,并且有一些令人不满意的解决方案。