如何在Cython中将Python对象转换为C++类型
How to convert Python object to C++ type in Cython
如何将使用 def
定义的 Cython 方法中的 Python 对象参数转换为 C++ 类型?我正在尝试为 C++ 库提供一个 Cython 包装类,如 Cython 文档的在 Cython 中使用C++部分所述。
这是一个演示我的问题的示例。
文件foo.h
:
namespace ns {
class Foo:
public:
Foo();
dosomething(std::shared_ptr<Bar>);
}
文件bar.h
:
namespace ns {
class Bar:
public:
Bar();
}
文件foo.pyx
:
from libcpp.memory cimport shared_ptr
cdef extern from 'bar.h' namespace 'ns':
cdef cppclass Bar:
Bar() except +
cdef extern from 'foo.h' namespace 'ns':
cdef cppclass Foo:
Foo() except +
void dosomething(shared_ptr[Bar])
cdef class PyBar:
cdef Bar* thisptr
def __cinit__(self):
self.thisptr = new Bar()
def __dealloc__(self):
del self.thisptr
cdef class PyFoo:
cdef Foo* thisptr
def __cinit__(self):
self.thisptr = new Foo()
def __dealloc__(self):
del self.thisptr
def dosomething(self, bar):
self.thisptr.dosomething(bar)
文件setup.py
:
from setuptools import Extension
from setuptools import setup
from Cython.Build import cythonize
extensions = [
Extension(
'foo',
sources=[
'foo.pyx',
'foo.cpp',
'bar.cpp',
],
language='c++',
include_dirs=['.'],
extra_compile_args=['-std=c++11'],
),
]
setup(
ext_modules=cythonize(extensions),
)
当我尝试编译它时发生的错误:
$ python setup.py build_ext
Compiling foo.pyx because it changed.
[1/1] Cythonizing foo.pyx
Error compiling Cython file:
------------------------------------------------------------
...
def __dealloc__(self):
del self.thisptr
def dosomething(self, bar):
self.thisptr.dosomething(bar)
^
------------------------------------------------------------
foo.pyx:38:33: Cannot convert Python object to 'shared_ptr[Bar]'
恐
怕不得不说,foo and bar
真的是一个愚蠢的例子,不知道C++代码想要完成什么,没有逻辑,没有实现。但是我也根据你的例子编造了一个如此愚蠢的例子,并让它起作用。这很棘手,而且有问题,希望对您有所帮助。
我使用 jupyter 笔记本来简化编译:
%%file foo.h
#include <memory>
namespace ns {
class Bar{
public:
Bar(){};
};
class Foo{
public:
Foo(): bar_addr(0) {}
void dosomething(std::shared_ptr<Bar> sp){bar_addr = (size_t)sp.get();}
size_t get_bar_addr(){return bar_addr;}
private:
size_t bar_addr;
};
}
赛通的零件:
%%cython -f -+ -a
# distutils: include_dirs = .
from libcpp.memory cimport shared_ptr
cdef extern from 'foo.h' namespace 'ns':
cdef cppclass Foo:
Foo() except +
void dosomething(shared_ptr[Bar])
size_t get_bar_addr()
cdef cppclass Bar:
Bar() except +
cdef class PyBar:
cdef Bar* thisptr
def __cinit__(self):
self.thisptr = new Bar()
def __dealloc__(self):
del self.thisptr
def addr(self):
return <size_t><void*>self.thisptr
cdef class PyFoo:
cdef Foo* thisptr
# There is a bug here, see the comments
cdef PyBar owned_bar # keep this bar to prevent the underlying pointer losing.
cdef shared_ptr[Bar] owned_bar_sp # keep this bar shared_ptr to prevent the underlying pointer from deleting.
def __cinit__(self):
self.thisptr = new Foo()
def __dealloc__(self):
del self.thisptr
def dosomething(self, PyBar bar):
self.owned_bar = bar
print("Address passed in: ", self.owned_bar.addr())
self.owned_bar_sp = shared_ptr[Bar](<Bar*><size_t>self.owned_bar.addr())
self.thisptr.dosomething(self.owned_bar_sp)
print("Address got : ", self.thisptr.get_bar_addr())
测试:
bar = PyBar()
foo = PyFoo()
foo.dosomething(bar)
关于您的问题"如何在Cython中将Python对象转换为C++类型",我认为答案是"可以"或"不能"或"可能",具体取决于上下文。在此特定示例中,"不能"。你必须在Cython中进行一些构造或转换,这可以充当Python和C/C++之间的坚实桥梁
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 将无符号char*转换为std::istream*C++