如何构建一个cython包装器的c ++函数与stl列表参数 [英] How to build a cython wrapper for c++ function with stl list parameter

查看:330
本文介绍了如何构建一个cython包装器的c ++函数与stl列表参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑下面的简单c ++代码。
(printlist.h)

Consider the following simple c++ code. (printlist.h)

#ifndef TESTLIB_H
#define TESTLIB_H

#include <iostream>
#include <list>

void printlist(std::list<int> &);

#endif

(printlist.c)

(printlist.c)

#include "printlist.h"

using namespace std;

void printlist(list<int> &l)
  {
  for(list<int>::const_iterator i = l.begin(); i != l.end(); i++)
  cout << *i << ' ';
  cout << endl;
  }

我的问题是如何使用这个代码与cython, that printlist
需要一个stl :: list。有没有办法使用extern声明这个?如果没有,使用这个函数的最简单的方法是什么。

My question is how to use this code with cython, the difficulty being the fact that printlist takes a stl::list. Is there a way to declare this using "extern"? If not, what is the simplest way to use this function.

.pyx)

 from libcpp.list cimport list

 cdef extern from "printlist.h":
         void printlist(std::list<int> &)

 cdef list[int] l = range(10)
 printlist(l)

(setup.py)

 from distutils.core import setup
 from distutils.extension import Extension
 from Cython.Distutils import build_ext

 ext_modules = [Extension("test", ["test.pyx", "printlist.C"], language='c++',)]

 setup(cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules)

我得到的错误信息如下:

The error message I get is the following:

Error compiling Cython file:
------------------------------------------------------------
...
from libcpp.list cimport list

cdef extern from "printlist.h":
        void printlist(std::list<int> &)
                          ^
------------------------------------------------------------

test.pyx:4:27: Expected an identifier or literal


推荐答案

您的代码有两个主要问题。

There are two primary issues with your code.

第一个是你在C文件中使用C ++。
开始重命名 printlist.c printlist.cpp

The first one is that you are using C++ in a C file. Start by renaming printlist.c to printlist.cpp

第二个是当你定义外部函数的调用签名时,你使用C ++语法作为函数声明,而不是像 http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#templates
这是导致您看到的错误的原因。

The second is that when you define the calling signature for the external function you use the C++ syntax for the function declaration instead of using braces for class templates as is described at http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#templates . This is what is causing the error you are seeing. The line

void printlist(std::list<int> &)

应替换为

void printlist(list[int] &)

另一件值得注意的事是Cython文件在编译时不会执行。
将测试用例包装在可从Python调用的函数中可能更容易。
这是一个工作示例。

Another thing that is worth noting is that Cython files are not executed upon compilation. It might be easier to wrap your test case in a function that is callable from Python. Here is a working example.

printlist.h (这与yours相同) / p>

printlist.h (This is the same as yours)

#ifndef TESTLIB_H
#define TESTLIB_H

#include <iostream>
#include <list>

void printlist(std::list<int> &);

#endif

printlist.cpp (我只更改文件扩展名和间距)

printlist.cpp (I only changed the file extension and the spacing)

#include "printlist.h"

using namespace std;

void printlist(list<int> &l){
    for(list<int>::const_iterator i = l.begin(); i != l.end(); i++)
    cout << *i << ' ';
    cout << endl;}

test.pyx
请注意,Cython可以自动从Python列表转换为C ++列表。
我在输入 list_test 函数的参数时这样做。
它还支持一些其他类型的自动转换,如 http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#standard-library

test.pyx Notice that Cython can convert automatically from a Python list to a C++ list. I'm doing this in the typing of the arguments for the list_test function. It also supports some other types of automated conversions as is mentioned at http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#standard-library

from libcpp.list cimport list

cdef extern from "printlist.h":
    void printlist(list[int] &)

def list_test(list[int] l):
    printlist(l)

setup.py (我也更改了这里的文件扩展名)

setup.py (I changed the file extension here as well)

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [Extension("test", ["test.pyx", "printlist.cpp"], language='c++',)]

setup(cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules)

test.py
这是一个Python脚本,用于调用 list_test function from test import list_test添加到 test.pyx

test.py This is a Python script to call the list_test function I added to test.pyx.

from test import list_test

list_test([1, 2, 3])

它应该打印字符串1 2 3。

When run, it should print the string "1 2 3".

这篇关于如何构建一个cython包装器的c ++函数与stl列表参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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