kru*_*kin 3 c++ python stl cython
考虑以下简单的c ++代码。(printlist.h)
#ifndef TESTLIB_H
#define TESTLIB_H
#include <iostream>
#include <list>
void printlist(std::list<int> &);
#endif
Run Code Online (Sandbox Code Playgroud)
(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;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如何在cython中使用此代码,困难之处在于printlist需要一个stl :: list的事实。有没有办法使用“ extern”来声明它?如果不是,使用此功能的最简单方法是什么。
(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)
Run Code Online (Sandbox Code Playgroud)
(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)
Run Code Online (Sandbox Code Playgroud)
我收到的错误消息如下:
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
Run Code Online (Sandbox Code Playgroud)
您的代码有两个主要问题。
第一个是您在C文件中使用C ++。首先重命名printlist.c为printlist.cpp
第二个是,当您为外部函数定义调用签名时,您使用C ++语法进行函数声明,而不是使用括号作为类模板,如http://docs.cython.org/src/userguide/wrapping_CPlusPlus所述。 html#templates。这就是导致您看到的错误的原因。线
void printlist(std::list<int> &)
Run Code Online (Sandbox Code Playgroud)
应该由
void printlist(list[int] &)
Run Code Online (Sandbox Code Playgroud)
您稍后在声明新列表时,在Cython文件中似乎已正确完成了此操作。
值得注意的另一件事是Cython文件不会在编译时执行。将测试用例包装到可从Python调用的函数中可能会更容易。这是一个工作示例。
printlist.h (这和你的一样)
#ifndef TESTLIB_H
#define TESTLIB_H
#include <iostream>
#include <list>
void printlist(std::list<int> &);
#endif
Run Code Online (Sandbox Code Playgroud)
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;}
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
test.py
这是一个Python脚本,用于调用list_test我添加到的函数test.pyx。
from test import list_test
list_test([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
运行时,应打印字符串“ 1 2 3”。
| 归档时间: |
|
| 查看次数: |
5126 次 |
| 最近记录: |