【发布时间】:2015-06-16 21:28:24
【问题描述】:
A.hpp
// A.hpp
#ifndef RECTANGLE_HPP
#define RECTANGLE_HPP
#include <iostream>
#include <vector>
namespace test {
double euclid_dist(const std::vector<double> & a) {
return 3.1415926;
}
template <class T,
double (*dist)(const std::vector<T> &)>
class foo {
public:
foo(std::vector<T> _items) {
items = _items;
}
~foo() {}
void inside() {
std::cout << "hello" << std::endl;
}
void func() {
inside();
}
void prt(std::vector<std::vector<T> > a) {
if(a.size() >= 1) {
std::cout << euclid_dist(a[0]) << std::endl;
}
}
private:
std::vector<T> items;
}; // class foo
} // namespace test
#endif
demo.pyx:
# demo.pyx
# distutils: language = c++
from libcpp.vector cimport vector
cdef extern from "A.hpp" namespace "test":
double euculid_dist(const vector [double] & a)
#def test_euclid_dist(const vector [double] a):
# return euclid_dist(a)
cdef extern from "A.hpp" namespace "test":
cdef cppclass foo [double, euclid_dist]:
foo (vector[double]) except +
void func()
void prt(vector[vector[double]])
cdef class PyFoo:
cdef foo *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, vec):
self.thisptr = new foo(vec)
def __dealloc__(self):
del self.thisptr
def func(self):
self.thisptr.func()
def prt(self, d):
self.thisptr.prt(d)
setup.py
from distutils.core import setup, Extension
from Cython.Build import cythonize
setup(ext_modules = cythonize(Extension(
"demo", # the extesion name
sources=["demo.pyx"], # the Cython source and additional C++ source files
language="c++", # generate and compile C++ code
)))
使用python setup.py build_ext --inplace 编译时,出现以下错误:
Compiling demo.pyx because it changed.
Cythonizing demo.pyx
running build_ext
building 'demo' extension
x86_64-pc-linux-gnu-g++ -pthread -fPIC -I/usr/include/python2.7 -c
demo.cpp -o build/temp.linux-x86_64-2.7/rect.o
demo.cpp:551:20: error: ‘euclid_dist’ was not declared in this scope
demo.cpp:551:31: error: template argument 2 is invalid
demo.cpp: In function ‘int __pyx_pf_4rect_5PyFoo___cinit__(__pyx_obj_4rect_PyFoo*, PyObject*)’:
demo.cpp:866:20: error: ‘euclid_dist’ was not declared in this scope
demo.cpp:866:31: error: template argument 2 is invalid
demo.cpp:866:43: error: invalid type in declaration before ‘;’ token
demo.cpp:881:38: error: ‘euclid_dist’ cannot appear in a constant-expression
demo.cpp:881:49: error: template argument 2 is invalid
demo.cpp:881:60: error: cannot convert ‘std::vector<double>’ to ‘int’ in initialization
demo.cpp: In function ‘PyObject* __pyx_pf_4rect_5PyFoo_4func(__pyx_obj_4rect_PyFoo*)’:
demo.cpp:984:26: error: request for member ‘func’ in ‘* __pyx_v_self->__pyx_obj_4rect_PyFoo::thisptr’, which is of non-class type ‘int’
demo.cpp: In function ‘PyObject* __pyx_pf_4rect_5PyFoo_6prt(__pyx_obj_4rect_PyFoo*, PyObject*)’:
demo.cpp:1038:26: error: request for member ‘prt’ in ‘* __pyx_v_self->__pyx_obj_4rect_PyFoo::thisptr’, which is of non-class type ‘int’
error: command 'x86_64-pc-linux-gnu-g++' failed with exit status 1
似乎在范围内找不到euclid_dist 函数,但我认为它在全局范围内..上面的代码有什么问题?谢谢!
【问题讨论】:
-
你真的是指
eculid而不是euclid吗?如果是这样,您是否一直这样拼写? -
另外,我从来没有尝试过将原始函数指针作为编译时模板参数从 Cython 传递……可能是您必须明确要求指向函数的指针?如果是这样,我不确定如何。但作为测试,您可能想尝试在 C++ 代码中创建一个全局
double (*eculid_dist_p)(const std::vector<T> &) = &eculid_dist,然后从 Cython 引用它而不是eculid_dist,看看是否可行。 -
@abarnert 在这种情况下,如何修改我的
pyx文件以从 cpp 文件导入变量? -
我不知道。但是你有没有做过我建议的测试,看看它是否有效?如果是这样,那么您有一个非常具体的问题,Cython 专家可能可以为您回答(如果他们不能,则为最后的解决方法);如果没有,那么至少我们有更多的信息。
标签: python c++ templates scope cython