Cython - 导入cython模块并将它们合并到单个共享对象

时间:2017-04-12 14:16:17

标签: python cython

我正在尝试使用Cython将python函数包装到C ++ apis中。我有2个模块sam1.pyx和sam2.pyx

## - sam1.pyx
import sam2
cdef public double calc(double x, double y):
  return sam2.calc_sub(x,y)

文件sam2.py的内容如下

## - sam2.py
def calc_sub(x, y):
  return x*y

使用这样的结构,生成包裹的sam1.h以及相应的sam1.so

在Cpp应用程序中使用

#include<iostream>
#include<Python.h>
#include"sam1.h"

using namespace std;

int main(){

  Py_Initialize();

  #if PY_MAJOR_VERSION < 3
   initsam1();
  #else
   PyInit_sam1();
  #endif  

  cout << "Starting Program!!"<<endl;

  cout << calc(3, 5);

  Py_Finalize();

  return 0;
}

未导入sam2.py(普通python)且错误为

Exception NameError: "name 'sam2' is not defined" in 'sam1.calc' ignored
你可以告诉我缺少什么吗?

1 个答案:

答案 0 :(得分:0)

问题1是您的模块初始化功能失败。在Python 3中,您需要针对NULL测试输出,然后打印错误(如果发生):

PyObject* m = PyInit_sam1();
if (m==NULL) {
    cout << "Module initialization failed!\n";
    if (PyErr_Occurred()) {
        PyErr_Print();
    }
}

(我不是100%肯定你为Python2做了什么,因为我觉得它没有返回任何东西。可能只是PyErr_Occurred)。这告诉你:

  

追踪(最近一次呼叫最后一次):

     

文件“sam1.pyx”,第2行,在init sam1(sam1.cpp:1094)

     

import sam2

     

ModuleNotFoundError:没有名为'sam2'的模块

这个追溯有望为您提供所需的线索 - 它找不到sam2。这是因为C api程序默认情况下当前目录不在路径上。您需要对其进行设置 - 以下代码在Py_Initialize之后但在模块初始化之前:

PyObject* path = PySys_GetObject("path");
// append "." to the path
PyObject* result = PyObject_CallMethod(path,"append","(s)",".");
Py_XDECREF(result);
// don't decref path though - it's borrowed

获取sys.path并向其添加.。之后一切正常。

注意 - 如果从其他目录调用程序,则“。”是指错误的地方。如果是这种情况,那么你需要做一些更聪明的事情并计算出目录的填充路径,可能来自argv[0]