2014-01-20 55 views
2

請考慮以下簡單的C++代碼。 (printlist.h)如何使用stl list參數爲C++函數構建一個cython包裝器

#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 ::名單。有沒有辦法使用「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) 

(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 

回答

3

機智有兩個主要問題你的代碼。

第一個是你在C文件中使用C++。 開始通過重命名printlist.cprintlist.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(I僅改變文件擴展名和間隔)

#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功能我添加到test.pyx

from test import list_test 

list_test([1, 2, 3]) 

運行時,應打印字符串「1 2 3」。

相關問題