考虑以下简单的c ++代码。 (printlist.h)
#ifndef TESTLIB_H
#define TESTLIB_H
#include <iostream>
#include <list>
void printlist(std::list<int> &);
#endif
(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中使用此代码,难点在于printlist 采用stl :: list。有没有办法使用&#34; extern&#34;来声明这个?如果没有,使用此功能的最简单方法是什么。
(test.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)
我收到的错误消息如下:
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
答案 0 :(得分:4)
您的代码存在两个主要问题。
第一个是您在C文件中使用C ++。
首先将printlist.c
重命名为printlist.cpp
第二个是当你为外部函数定义调用签名时,你使用函数声明的C ++语法,而不是像http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#templates中描述的那样使用类模板的大括号。 这是导致您看到的错误的原因。 这条线
void printlist(std::list<int> &)
应替换为
void printlist(list[int] &)
在声明新列表时,您似乎稍后在Cython文件中正确完成了此操作。
另一件值得注意的事情是Cython文件在编译时不会执行。 将测试用例包装在可从Python调用的函数中可能更容易。 这是一个有效的例子。
printlist.h
(这与你的相同)
#ifndef TESTLIB_H
#define TESTLIB_H
#include <iostream>
#include <list>
void printlist(std::list<int> &);
#endif
printlist.cpp
(我只更改了文件扩展名和间距)
#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
from libcpp.list cimport list
cdef extern from "printlist.h":
void printlist(list[int] &)
def list_test(list[int] l):
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.cpp"], language='c++',)]
setup(cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules)
test.py
这是一个Python脚本,用于调用我添加到list_test
的{{1}}函数。
test.pyx
运行时,应打印字符串“1 2 3”。