2

我正在寻找一种在 cython 文件中添加预编译器逻辑的解决方案。

我为 C++ 中的硬件设备 API 编写了一个 cython 包装器。这是一个 cython 项目,通常使用 MSVC 为 python 2.7 和 3.6 编译。整个包是用 cython 编写的,不需要外部 c++ 或头文件。

最初,我编写这个软件是为了在 Windows 机器上使用,所以我使用了一些基本的 winapi 函数来帮助访问内核事件循环和 winapi 错误消息。它工作得很好,但我还想添加跨平台编译的功能。这需要我完全替换几个关键功能才能使其在linux机器上工作。例如,硬件 API 甚至根据操作系统具有不同的事件处理功能。此外,winapi 事件处理也需要更换。

现在,我将整个项目一起编译成一个模块以简化导入。所有代码都驻留在编译成文件的同一个 pyx 文件中hwmodule.pyd。但是,为了实现跨平台编译的目标,我需要在设置时将几个小的 pyx 文件一起修补。该解决方案不优雅且难以维护。更不用说,这更难培训可能想要添加到项目中的其他人。

理想情况下,我可以将 cython 编写为 c 编译时标志,这些标志根据标志或变量进行解释和编译。cython 中是否有任何解决方案可以实现我的目标?或者,是否有一个不同的组织可以优雅且易于维护?

一些与 c 或 python 中的语法相似的合理语法示例(可能存在也可能不存在):

  • 使用#ifdef或类似的陈述

    #ifdef __WINAPI
    def foo():
        print('bar win')
    #else
    def foo():
        print('bar linux')
    #endif
    
  • 使用类似 python 的with

    with ifdef('__WINAPI'):
        def foo():
            print('bar win')
    
  • 以类似 cython 的行结尾结束函数

    def foo() ifdef('__WINAPI'):
        print('bar win')
    
    def foo() ifndef('__WINAPI'):
        print('bar win')
    
4

1 回答 1

6

从评论扩展的简短答案:这是Cython 支持的功能。它允许您定义编译时常量

DEF a = 5

并根据这些常量有条件地包含代码:

IF a==5:
    cdef f():
        return 1
ELSE:
    cdef f():
        return 2

它还定义了一些有用的常量:UNAME_SYSNAME例如让您在 Windows、OS X 和 Linux 之间进行选择。


这些表达式在 Cython 在您的 .pyx 文件上运行时进行评估 - 因此生成的 C 代码在 Windows 和 Linux 上是不同的,因此如果您想在另一个平台上编译,您需要重新运行 Cython,而不是只是重新编译C文件。


Cython中没有直接等效的 C #ifdef/ #ifndef- 测试是否定义了编译时间常数不是受支持的功能。

于 2017-11-14T18:23:21.150 回答