通过C ++调用具有多个pyx文件的cython库 [英] Calling a cython library with multiple pyx files through c++

查看:228
本文介绍了通过C ++调用具有多个pyx文件的cython库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要从C ++应用程序调用的python项目。我想将所有python源捆绑在一起在一个共享库中,并将c ++应用程序链接到该库。现在,我的cython setup.py为每个python源创建了一个 *。so ,这非常不方便。

I have a python project that I want to call from a c++ application. I would like to bundle all python sources together in a single shared library and link the c++ application to that library. Right now my cython setup.py creates one *.so per python source, which is very inconvenient.

这里是 setup.py 文件:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

sourcefiles = ['project_interface.pyx', 'impl_file1.pyx']

setup(
    ext_modules = cythonize(sourcefiles)
)

project_interface.pyx :

project_interface.pyx :

# distutils: language = c++

import impl_file1

cdef public void HelloWorld():
    print "Calling Hello World"
    impl_file1.helloworld_func()

impl_file1.pyx:

impl_file1.pyx :

def helloworld_func():
    print 'Hello World'

我试图修改setup.py以将所有python代码捆绑在一个库中,如下所示:

I tried to modify setup.py to bundle all python code in a single library like this:

setup(
      ext_modules = cythonize([Extension("my_project", sourcefiles, language='c++')])
)

不幸的是,当执行 void HelloWorld()时,应用程序无法再提交impl_file1了。我得到了:

Unfortunately, when executing void HelloWorld(), the application cannot file impl_file1 anymore. I get :

Calling Hello World
NameError: name 'impl_file1' is not defined
Exception NameError: "name 'impl_file1' is not defined" in 'project_interface.HelloWorld' ignored

驱动此操作的c ++程序是:

The c++ program driving this is:

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

int main(int argc, const char** argv){
    Py_Initialize();
    initproject_interface();
    HelloWorld();
    Py_Finalize();


    return 0;
}

使用多个 *进行编译时,此应用程序可以正常工作。这样的文件。

This application works correctly when compiling with multiple *.so files.

在两种情况下,编译都非常简单:

Compilation is very straightforward in either cases:

python setup.py build_ext --inplace
mv my_project.so libmy_project.so
g++ main.cpp -o main `python2-config --cflags --ldflags` -L. -lmy_project

有没有办法使单个共享库解决方案正常工作?

Is there any way to get the single shared library solution to work?

推荐答案

关于将多个Cython模块捆绑在一起,存在许多类似的问题(例如 1 2 ),实际上并不可行,因为Python使用文件路径来处理模块。但是,这个问题并不完全相同,因为您是从C ++调用的,这为您提供了一个额外的选择。

There's a number of similar looking questions about bundling multiple Cython modules together (e.g. 1, 2) which isn't really viable because Python uses file paths to handle modules. However, this question isn't quite the same because you're calling it from C++, which gives you an extra option.

您需要使用C API函数< a href = https://docs.python.org/2/c-api/import.html#c.PyImport_AppendInittab rel = nofollow noreferrer> PyImport_AppendInittab 转换为Python,将 impl_file1 视为内置模块,因此它不会在路径中搜索要导入的文件。首先提供导入函数的声明(因为您不会从头文件中获得该声明):

You need to use the C API function PyImport_AppendInittab to Python to treat impl_file1 as a builtin module so it doesn't search the path for a file to import. Start by providing a declaration of the import function (since you won't get that from your header file):

extern "C" {
// PyObject* PyInit_impl_file1(); // Python 3
void initimpl_file1(); // Python 2
}

然后在 main中,在 Py_Initialize 之前,添加:

Then, in main, before Py_Initialize, add:

PyImport_AppendInittab("impl_file1", initimpl_file1); // change the name for Python 3

这篇关于通过C ++调用具有多个pyx文件的cython库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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