简体   繁体   English

在C ++程序中调用Cython(Python3.6)

[英]Call Cython (Python3.6) in C++ Program

I'm working on a project where I need to embed some python code in C++. 我正在一个项目中,我需要在C ++中嵌入一些python代码。 I've been trying Cython for a while, but I still have a lot of questions. 我已经尝试使用Cython了一段时间,但仍然有很多问题。 Here's a demo that I have tried. 这是我尝试过的演示。

Here I have a couple files with struct and functions: 在这里,我有几个带有struct和函数的文件:

First, this is file cat.pyx 首先,这是文件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

And its .pxd file cat.pxd : 及其.pxd文件cat.pxd

cdef public struct Cat:
    int num

cdef public setCatNum(Cat* )
cdef public int getCatNum(Cat* )

And this is my setup.py : 这是我的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}}
)

It could compile correctly, but in the generated cat.h file, the function declarations are something else: 它可以正确编译,但是在生成的cat.h文件中,函数声明是其他内容:

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

So how could I call those functions in my C/C++ program? 那么,如何在C / C ++程序中调用这些函数呢? Thank you in advance. 先感谢您。

I'm not sure why it's generating mangled names for the public functions - it runs contrary to the documentation . 我不确定为什么它会为公共函数生成错误的名称-它与文档相反。 However it's also doing it for me. 但是它也为我做着。 I suspect this is a bug, but suggest for the moment you should just use the mangled names. 我怀疑这是一个错误,但建议您暂时只使用变形的名称。

You probably want to set the return type of setCatNum to void . 您可能需要将setCatNum的返回类型设置为void Currently it returns a PyObject* (always None ) which isn't useful, and means you have to handle its reference count. 当前,它返回一个PyObject* (总是None ),它没有用,这意味着您必须处理其引用计数。

cdef public void setCatNum(Cat* )

The thing I think you're getting confused by is the difference between Python 2 and 3. The documentation suggests replacing init<modulename> with 我想让您感到困惑的是Python 2和3之间的区别。文档建议将init<modulename>替换为

err = PyImport_AppendInittab("modulename", PyInit_modulename);
Py_Initialize();
modulename_module = PyImport_ImportModule("modulename");

That's the only change you need to make - you don't actually need to use the module object. 这是您唯一需要做的更改-实际上不需要使用模块对象。

A working example: 一个工作示例:

#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();
}

compiles successfully on Linux with 在Linux上成功编译

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

(You may have to change the exact cat filename) (您可能必须更改确切的cat文件名)

The normal cython development pattern is quite the opposite - you would use it to call C++ code from python, instead. 常规的cython开发模式则相反-您将使用它来从python调用C ++代码。

A simple description of cython common usage is "Write your code in high-level python-like language and it gets converted to C source code for a python extension" cython常用用法的简单描述是“以类似python的高级语言编写代码,并将其转换为python扩展的C源代码”

The generated C code is not readable, and not meant to be used from C. 生成的C代码不可读,也不打算从C使用。

tl;dr Use cython to make your C/C++ program callable from python, and write python code to call it. tl; dr使用cython使您的C / C ++程序可从python调用,并编写python代码来调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM