Cython 在 `double (s.time_since_epoch().count())` 上返回 `Cython.Compiler.Errors.CompileError`
Posted
技术标签:
【中文标题】Cython 在 `double (s.time_since_epoch().count())` 上返回 `Cython.Compiler.Errors.CompileError`【英文标题】:Cython returns a `Cython.Compiler.Errors.CompileError` on `double (s.time_since_epoch().count())` 【发布时间】:2017-02-26 11:45:08 【问题描述】:问题描述:
我想在 Python 中使用 Cython
访问 C++
对象。
运行 python2 setup.py build_ext -i
时,我得到一个 Cython.Compiler.Errors.CompileError
你能看看下面,告诉我应该改变什么来让 Cython 编译我的代码吗?
当我尝试用 Cython 编译时,我得到:
$ python2 setup.py build_ext -i
Compiling ds5.pyx because it changed.
[1/1] Cythonizing ds5.pyx
Error compiling Cython file:
------------------------------------------------------------
...
cdef cppclass os_time_service:
#double get_time() const override
double get_time()
#static_cast<double>(ts.time_since_epoch().count())
double (s.time_since_epoch().count())
^
------------------------------------------------------------
ds5.pyx:15:37: Expected '.', found 'count'
Traceback (most recent call last):
File "setup.py", line 5, in <module>
ext_modules = cythonize("ds5.pyx"))
File "/usr/local/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 934, in cythonize
cythonize_one(*args)
File "/usr/local/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 1056, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: ds5.pyx
h
文件中的相关行是:
$ view backend.h
#ifndef LIBREALSENSE_BACKEND_H
#define LIBREALSENSE_BACKEND_H
#include "../include/librealsense/rs.h" // Inherit all type definitions in the public API
#include <memory> // For shared_ptr
#include <functional> // For function
#include <thread> // For this_thread::sleep_for
#include <vector>
#include <algorithm>
#include <set>
#include <list>
const uint16_t VID_INTEL_CAMERA = 0x8086;
namespace rsimpl
namespace uvc
class time_service
public:
virtual double get_time() const = 0;
~time_service() = default;
;
class os_time_service: public time_service
public:
double get_time() const override
auto ts = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
return static_cast<double>(ts.time_since_epoch().count());
;
...
我的 pyx 文件是:
$ cat ds5.pyx
# distutils: language = c++
# distutils: sources = uvc-v4l2.cpp
cdef extern from "backend.h" namespace "rsimpl::uvc":
#const uint16_t VID_INTEL_CAMERA = 0x8086
const unsigned short VID_INTEL_CAMERA = 0x8086
cdef cppclass time_service:
#virtual double get_time() const = 0
double get_time()
cdef cppclass os_time_service:
#double get_time() const override
double get_time()
#static_cast<double>(ts.time_since_epoch().count())
double (s.time_since_epoch().count())
cdef class os_time_service_c:
cdef os_time_service *_os_time_service_ptr
def __cinit__(self):
self._os_time_service_ptr = new os_time_service()
if self._os_time_service_ptr == NULL:
raise MemoryError()
def __dealloc__(self):
if self._os_time_service_ptr != NULL:
del self._os_time_service_ptr
cpdef double get_time(self):
return self._os_time_service_ptr.ts.time_since_epoch().count()
环境:
Ubuntu 16.04
Python 2.7.12
Cython 0.25.2
【问题讨论】:
【参考方案1】:删除线
double (s.time_since_epoch().count())
解释: Cython 只需要知道函数 double get_time()
存在 - 它不需要知道实现(由您的 C++ 代码提供)。因此,无需尝试在 Cython 中重写实现。
我没有详细查看您的其余代码,因此那里也可能存在问题。不过有几个小cmets:
在构造函数中:
if self._os_time_service_ptr == NULL:
raise MemoryError()
这是不必要的,因为如果分配失败,现代 C++ 会引发 std::bad_alloc
,而不是返回 NULL
(并且 Cython 会自动将其转换为 MemoryError
)。
在析构函数中
if self._os_time_service_ptr != NULL:
是不必要的,因为删除NULL
是安全的。不过,这些都不会引起问题。
【讨论】:
以上是关于Cython 在 `double (s.time_since_epoch().count())` 上返回 `Cython.Compiler.Errors.CompileError`的主要内容,如果未能解决你的问题,请参考以下文章