首页 > 解决方案 > 如何从 C++ 标头导入全局变量以在 Cython 中使用

问题描述

我正在开发一个需要用 Cython 包装的 C++ 项目,以便最终用于 Python 的集成测试。我有一个全局变量,用于在我的 C++ 头文件中的函数中默认一个值,看起来像

header file
const uint8_t kAudioLevel = 0x5a;

这用于 c++ 文件中的函数中,例如

void func(uint audioLevel=kAudioLevel)

我在 Cython 中包装了这个函数,目前在我的 .pyx 文件中使用了另一个同名的变量,例如

DEF kAudioLevel

这个默认值被传递到 C++ 中的 func() 包装器中,以允许该值被默认。但是,我真的很想让包装器中使用的这个变量直接从头文件中导入,所以我有一个单一的事实来源,不必每次都更改这个变量两次。我尝试添加以下内容:

pxd file
cdef extern from "header.h":
cdef cppclass Class:
    int kAudioLevel

然后尝试像这样直接在 .pyx 中使用 kAudioLevel

def func(audioLevel = kAudioLevel):
return client.func(audioLevel)

这是为了让我们可以在 Cython 和 C++ 中默认设置该值,而不必对其进行两次编辑。但是,当我尝试此操作时未找到该变量。不确定我是否必须将标头类添加到 pxd 和 pyx 文件以及如何执行此操作。我查看了 Cython 文档,但没有发现任何有用的东西。

标签: pythonc++cython

解决方案


对于const像这样的成员cpy.hh

#ifndef CPY_HH
#define CPY_HH

#include <cstdint>

const uint8_t kAudioLevel = 5;

#endif

cytest.pyx

from libc.stdint cimport uint8_t

cdef extern from "cpy.h":
    cdef uint8_t kAudioLevel

允许我kAudioLevel在我的.pyx文件中使用。使用 aexposedKAudioLevel = kAudioLevel我可以将其暴露给模块外部。

如果你想要一个真正的全局变量,那就有点复杂了,但是cpy.hh

#ifndef CPY_HH
#define CPY_HH

#include <cstdint>

extern uint8_t kAudioLevel;

#endif

cpy.cc

#include "cpy.hh"

uint8_t kAudioLevel = 5;

和上面一样,我可以从和中cytest.pyx创建一个我可以访问和修改的变量。.pyx.cc

不幸的是,它没有暴露给外部导入器,所以要访问/修改,就我所见,kAudioLevel需要帮助函数,比如getVal(), 。setVal(newVal)


推荐阅读