C++程序中调用Cython(Python 3.6)

2024-06-17 08:00:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一个项目,我需要在C++中嵌入一些Python代码。我已经试了一段时间了,但我还是有很多问题。这是我试过的一个演示。在

这里我有几个包含结构和函数的文件:

首先,这是文件cat.pyx

cdef public struct Cat:
    int num

cdef public setCatNum(Cat* cat):
    cat.num = 100

cdef public int getCatNum(Cat* cat):
    return cat.num

及其.pxd文件cat.pxd

^{pr2}$

这是我的setup.py

from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [
    Extension("cat", ["cat.pyx"], include_dirs=['.']),
    ]

setup(
  name='dotest',
  cmdclass={'build_ext': build_ext},
  ext_modules=ext_modules,
  script_args=['build_ext'],
  options={'build_ext':{'inplace':True, 'force':True}}
)

它可以正确编译,但在生成的cat.h文件中,函数声明是其他内容:

__PYX_EXTERN_C PyObject *__pyx_f_3cat_setCatNum(struct Cat *); __PYX_EXTERN_C int __pyx_f_3cat_getCatNum(struct Cat *);

我如何调用C/C++程序中的这些函数?提前谢谢你。在


Tags: 文件函数buildmodulespublicnumextstruct
2条回答

我不知道它为什么会为公共函数生成混乱的名称-它的运行与the documentation相反。但它也在为我做这件事。我怀疑这是一个bug,但建议您暂时只使用损坏的名称。在

您可能需要将setCatNum的返回类型设置为void。目前它返回一个PyObject*(总是None),这是没有用的,意味着您必须处理它的引用计数。在

cdef public void setCatNum(Cat* )

我想你会被Python2和3的区别弄糊涂了。文档建议将init<modulename>替换为

^{pr2}$

这是您需要做的唯一更改-实际上不需要使用模块对象。在

一个有效的例子:

#include <Python.h>
#include "cat.h"
#include <iostream>

int main() {

    auto err = PyImport_AppendInittab("cat", PyInit_cat);
    if (err) {
        std::cout << "ERROR!\n";
        return 1;

    }
    Py_Initialize();
    auto cat_module = PyImport_ImportModule("cat"); // you don't actually have to do anything with this module object
    Cat c;
    __pyx_f_3cat_setCatNum(&c);
    std::cout << __pyx_f_3cat_getCatNum(&c) << "\n";
    Py_Finalize();
}

使用在Linux上成功编译

g++ example_cpp.cpp -o example `python3-config  includes  libs` ./cat.cpython-36m-x86_64-linux-gnu.so

(您可能需要更改cat文件名)

正常的Cython开发模式正好相反——你会用它来代替Python的C++代码。在

cython常见用法的一个简单描述是“用类似python的高级语言编写代码,然后将其转换为python扩展的C源代码”

生成的C代码是不可读的,也不打算从C中使用

使用Python调用Cy/C++程序,并调用Python代码调用它。在

相关问题 更多 >