python - 通过模块将 C++ 类暴露给 cython
问题描述
我想要做什么:安装一个 python/cython 模块,公开一个 c++ 类,并在以后cimport
的任何.pyx
文件中使用它。
什么不起作用:安装模块后,我无法管理cimport
文件。cython 编译正在工作,因为我可以在纯 python 中使用包装类。
文件结构:
├── cytest
│ ├── cywrappers
│ │ ├── cynode.pxd
│ │ └── cynode.pyx
│ └── hpp
│ └── node.hpp
└── setup.py
节点.hpp:
#ifndef graph_HPP
#define graph_HPP
class Node
{
public:
int ID;
double value;
Node(){;};
Node(int tid, double tvalue)
{this->ID = tid; this->value = tvalue;}
void multiplicate(double num){this->value = this->value * num;}
};
#endif
cynode.pxd
cdef extern from "node.hpp":
cdef cppclass Node:
Node()
Node(int tid, double tvalue)
int ID
double value
void multiplicate(double num)
cynode.pyx
cimport cynode
cdef class pynode:
cdef cynode.Node c_node
def __cinit__(self, int tid, double tval):
self.c_node = cynode.Node(tid,tval)
def print_val(self):
print("ID: ", self.c_node.ID, "value: ", self.c_node.value)
def multiplicate(self, mul):
self.c_node.multiplicate(mul)
和setup.py
:
from setuptools import setup, find_packages, Extension
from Cython.Distutils import build_ext
import numpy as np
setup(
name = "pycytest",
packages=find_packages(include=['cytest', 'cytest.*']),
package_data={'': ['*.pxd', '*.pyx', '*.hpp']},
zip_safe=False,
ext_modules=
[Extension("cytest.cywrappers.cynode",
sources = ["cytest/cywrappers/cynode.pyx"],
language="c++", extra_compile_args=["-O3", "-std=c++11"],
include_dirs=["./cytest/hpp/", np.get_include()])],
cmdclass = {'build_ext': build_ext}
)
我安装pip install .
并尝试在jupyter notebook
(从另一个位置)使用它。
import cytest.cywrappers.cynode as cynode
node = cynode.pynode(5, 7.6)
node.print_val()
node.multiplicate(67)
node.print_val()
应有的输出:
('ID: ', 5, 'value: ', 7.6)
('ID: ', 5, 'value: ', 509.2)
但是,如果我尝试以下任何一行:
%%cython --cplus
# from cytest cimport cywrappers
# cimport cytest
# cimport cynode
我总是得到一个'XXX.pxd' not found
.
有人有解决方案吗?我搜索了很长时间,恐怕我找不到正确的关键字。
解决方案
我设法让它工作:
- 我重命名了扩展名以适应
pyx
- 我确保
pxd
导入的hpp
相对导入(cdef extern from "../hpp/node.hpp":
) - 最后,为了
package_data
找到并包含存储库中的所有文件(需要在以后重用代码),我在每个目录中pyx
添加了一个空文件。__init__.py
现在我可以了cimport cytest.cywrappers.cynode as cynode
。
我尝试了很多东西,所以所有的编辑都不相关,但这是一个工作setup.py
:
from setuptools import setup, find_packages, Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
import numpy as np
extension = cythonize( [Extension("cytest.cywrappers.cynode",
sources = ["cytest/cywrappers/cynode.pyx"],
language="c++", extra_compile_args=["-O3", "-std=c++11"],
include_dirs=["./cytest/hpp/", np.get_include()])], compiler_directives = {"language_level": 3, "embedsignature": True})
setup(
name = "pycytest",
packages=find_packages(include=['cytest', 'cytest.cywrappers']),
package_data={"cytest": ["./*/*.pyx", "./*/*.pxd", "./*/*.hpp" ]},
zip_safe=False,
ext_modules=extension
,
cmdclass = {'build_ext': build_ext}
)
推荐阅读
- list - PowerQuery:如何用多列的每列名称替换文本
- bash - 使用 bash 获取活动的 kerberos 主体
- javascript - Javascript在恢复功能之前等待按钮按下
- angular - 垫子图标不显示
- javascript - 如何使用 .env 文件制作登录屏幕?
- swift - RxSwift 和 AVKit 的问题
- python-3.x - 如何在 PyQt5 的列表小部件中添加图像?
- javascript - 带有 useEffect 和 React Native 的 socket.IO 不会多次更新 Redux 状态
- excel - 有没有办法在 32 位 Excel 的 VBA 中存储 64、128 或 256 字节值?
- html - 超过页面末尾的下拉菜单