在C ++中使用Python对象 [英] Using Python objects in C++

查看:97
本文介绍了在C ++中使用Python对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个代码,该代码使用间隔分析的方法来计算非线性映射的图像,应用minkowski和,并重复任意次数的迭代。

I'm writing a code that calculates the images of nonlinear maps using methods from interval analysis, applies a minkowski sum and repeats for an arbitrary number of iterations.

我已经用Python编写了一个有效的代码,但是我希望能够在C ++中实现该算法中迭代/递归密集型的某些部分,以从提高的速度中受益。过去我使用Cython取得了不错的效果,但是我想练习C ++。

I've written a working code in Python, however I would like to be able to implement some of the more iteration/recursion intensive parts of the algorithm in C++ to benefit from the increased speed. I have used Cython in the past with great results, but I'd like to practice my C++.

此外,我的对象非常复杂,因此我宁愿避免使用

Also, my objects are complicated enough that I'd rather avoid having to implement them in C++ (baby steps!).

所以我的问题是:

1)是否使用

2)否则,是否可以使用Cython来包装在python对象上迭代/递归的C ++函数?

2) If not, is it possible to use Cython to wrap a C++ function which iterates/recurses over a python object?

更具体地说,我有一个递归算法,它可以对BST的左右子对象进行递归(尽管它是一个经过大量修改的BST,所以我宁愿不要(不了解在C ++中实现它的细节),但是运行时非常禁止,所以我想用C ++编写它。

To be more specific, I have a recursive algorithm that recurses over the left and right children of a BST (though it's a fairly heavily modified BST so I'd rather not get bogged down with the details of implementing it in C++), however the runtime is quite prohibitive, so I'd like to write it in C++.

推荐答案

是。使用纯 C / C ++ 可以提高纯Python的速度,但与增加的速度不相称。如果要处理Python对象,则需要通过 Python C / API ;这增加了执行的开销,这是允许与Python交互所必须付出的代价。

Yes. You will get a speed-up over pure python but not on par with the increase you'd get if you were using pure C/C++. If you want to handle Python Objects you'll need to do it via the Python C/API; this adds overhead to the execution, the price you must pay for being allowed to interact with Python.

请注意,这涉及很多复杂性,因为您需要熟悉API并阅读使用对象引用执行的功能,如何创建列表,打包元组等。等等如果仅创建几个将方法包装在对象上的 public Cython cdef 函数,则可以跳过所有这些操作。这样会生成所有 CPython 代码来为您处理这些代码。

Do note this involves a lot of complexity since you need to be familiar with the API and read up what functions do with object references, how to create Lists, pack Tuples et cetera. You can skip through all these if you just create a couple of public Cython cdef functions that wrap the methods on your objects. This generates all the CPython code that handles these for you.

一个包裹了一个愚蠢对象的小例子并且嵌入式可能看起来像这样(请注意,我为此使用 .c c ++ 具有类似的步骤):

A little example in which a silly object is wrapped and embedded might look like this (note, I'm using .c for this, c++ has similar steps):

class PyClass(object):

    def __init__(self):
        self.data = []

    def add(self, val):
        self.data.append(val)

    def __str__(self):
        return "Data: " + str(self.data)

cdef public object createPyClass():
    return PyClass()

cdef public void addData(object p, int val):
    p.add(val)

cdef public char* printCls(object p):
    return bytes(str(p), encoding = 'utf-8')

使用 cython pycls.pyx (将-cplus 用于 c ++ )将生成 .c .h 文件,其中包含源代码和函数decla口粮。现在您需要做的就是创建一个 main.c 文件,该文件启动Python,您可以调用以下函数了:

Compiling with cython pycls.pyx (use --cplus for c++) will generate a .c and .h file containing the source and the function declarations respectively. All you need to do now is create a main.c file that starts up Python and you're ready to call these functions:

#include "Python.h"   // Python.h always gets included first.
#include "pycls.h"    // Include your header file.

int main(int argc, char *argv[])
{
    Py_Initialize();   // initialize Python
    PyInit_pycls();    // initialize module (initpycls(); in Py2)
    PyObject *obj = createPyClass();
    for(int i=0; i<10; i++){
        addData(obj, i);
    }
    printf("%s\n", printCls(obj));
    Py_Finalize();
    return 0;
}

使用适当的标志进行编译(您可以从 python3.5-config python-config [Py2]):

Compiling this with the proper flags (which you can obtain from python3.5-config of python-config [Py2]):

gcc pycls.c main.c -L$(python3.5-config --cflags) -I$(python3.5-config --ldflags) -std=c99

将创建与对象交互的可执行文件:

Will create your executable which interacts with your object:

./a.out
Data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

所有这些都是通过使用 Cython public 关键字,它生成 .h 头文件。您也可以使用Cython编译python模块,然后自己创建头文件/处理其他样板文件。既然我不希望您被 C-API 所困扰,那不应该是这样。

All this is done by using Cython along with the public keyword that generates the .h header file. You could alternatively just compile a python module with Cython and create the header/handle the additional boilerplate yourself. Since I don't think you want to get boggled down with C-API learning, this shouldn't be the way to go.

正如@freakish在他的评论中指出的那样,提取数据非常理想( numpy 具有 C-API ),然后在纯 C ++ 上进行处理。通常,如果您在 C / C ++ 中进行循环并在那里进行艰苦的工作,则可以提高速度。

As @freakish states in his comment, it would be ideal to extract the data (numpy has a C-API you can use for this) and work on it in pure C++. Generally if you work your loops in C/C++ and perform the grunt work there, you'll get good speed ups.

这篇关于在C ++中使用Python对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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