Cython-导入cython模块并将其合并到单个共享库中 [英] Cython - importing cython modules and merging them into single shared object

查看:92
本文介绍了Cython-导入cython模块并将其合并到单个共享库中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to wrap python functions to C++ apis using Cython. I have 2 modules sam1.pyx and sam2.pyx

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

文件sam2.py的内容如下

the contents of the file sam2.py is as follows

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

具有这种结构,将生成包装的 sam1.h 以及相应的 sam1.so

with such a structure, the wrapped sam1.h along with the corresponding sam1.so are generated

在Cpp应用程序中使用期间,

During the usage in Cpp application,

#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),错误为

the sam2.py (normal python) is not imported and the error is

Exception NameError: "name 'sam2' is not defined" in 'sam1.calc' ignored

能否让我知道缺少了什么?

Could you please let me know what is missing?

推荐答案

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

Problem 1 is that your module initialization function is failing. In Python 3 you need to test the output against NULL, and then print the error (if it occurred):

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

(我不确定100%对Python2做什么,因为我认为它不会返回任何内容.可能只是 PyErr_Occurred ).这告诉您:

(I'm not 100% sure what you do for Python2 since I think it doesn't return anything. Probably just PyErr_Occurred). This tells you:

回溯(最近通话最近一次):

Traceback (most recent call last):

init sam1中的文件"sam1.pyx",第2行(sam1.cpp:1094)

File "sam1.pyx", line 2, in init sam1 (sam1.cpp:1094)

导入sam2

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

ModuleNotFoundError: No module named 'sam2'

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

This traceback hopefully gives you the clue you need - it's not finding sam2. This is because the current directory isn't on the path by default for C api programs. You need to set it up so that it is - the following code goes after Py_Initialize but before the module initialization:

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 并将.附加到它.之后,一切正常.

It gets sys.path and appends . to it. After that everything works fine.

注意-如果您从其他目录调用程序,则.".指错误的地方.如果是这种情况,那么您需要做一些更聪明的事情,并找出目录的填充路径,可能是从 argv [0] 开始.

Note - if you call your program from a different directory then "." refers to the wrong place. If this is the case then you need to do something cleverer and work out the fill path to the directory, probably from argv[0].

这篇关于Cython-导入cython模块并将其合并到单个共享库中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆