通过模块向cython公开c++类



我想做什么:安装一个python/cython模块,该模块公开一个c++类,并且以后可以在任何.pyx文件中cimport它。

什么不起作用:安装模块后,我无法管理cimport文件。cython编译正在工作,因为我可以在纯python中使用封装的类。

文件结构:

├── cytest
│   ├── cywrappers
│   │   ├── cynode.pxd
│   │   └── cynode.pyx
│   └── hpp
│       └── node.hpp
└── setup.py

node.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在相对导入(cdef extern from "../hpp/node.hpp":(中导入了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}
)

相关内容

  • 没有找到相关文章

最新更新