我正在尝试使用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
你可以告诉我缺少什么吗?
答案 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]
。