Cython 预编译器决策
Cython Precompiler decision making
我正在寻找在 cython 文件中添加预编译器逻辑的解决方案。
我用 C++ 为硬件设备 API 编写了一个 cython 包装器。这是一个 cython 项目,通常使用 MSVC 为 python 2.7 和 3.6 编译。整个包都是用cython写的,不需要外部c++或者头文件。
最初,我编写这个软件是为了在 windows 机器上使用,所以我使用了一些基本的 winapi 函数来帮助访问内核事件循环和 winapi 错误消息。它工作得很好,但我还想添加跨平台编译功能。这需要我完全替换几个关键函数才能使其在 linux 机器上运行。例如,硬件 API 甚至根据 OS 具有不同的事件处理函数。此外,需要替换 winapi 事件处理。
现在,我将整个项目一起编译成一个模块以简化导入。所有代码都驻留在编译成 hwmodule.pyd
文件的同一个 pyx 文件中。但是,为了实现跨平台编译的目标,我需要在安装时将几个小的 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')
从评论扩展而来的简短回答:这是 a feature that Cython supports。它允许您定义编译时间常量
DEF a = 5
并根据这些常量有条件地包含代码:
IF a==5:
cdef f():
return 1
ELSE:
cdef f():
return 2
它还定义了一些有用的常量:例如,UNAME_SYSNAME
让您可以在 Windows、OS X 和 Linux 之间进行选择。
这些表达式在您的 .pyx 文件上的 Cython 是 运行 时被评估 - 因此生成的 C 代码在 Windows 和 Linux 上是不同的,所以如果您想要要在另一个平台上编译,您需要重新运行 Cython,而不仅仅是重新编译 C 文件。
在 Cython 中没有 C #ifdef
/#ifndef
的直接等价物 - 测试是否定义了编译时间常量是 不 支持的功能。
我正在寻找在 cython 文件中添加预编译器逻辑的解决方案。
我用 C++ 为硬件设备 API 编写了一个 cython 包装器。这是一个 cython 项目,通常使用 MSVC 为 python 2.7 和 3.6 编译。整个包都是用cython写的,不需要外部c++或者头文件。
最初,我编写这个软件是为了在 windows 机器上使用,所以我使用了一些基本的 winapi 函数来帮助访问内核事件循环和 winapi 错误消息。它工作得很好,但我还想添加跨平台编译功能。这需要我完全替换几个关键函数才能使其在 linux 机器上运行。例如,硬件 API 甚至根据 OS 具有不同的事件处理函数。此外,需要替换 winapi 事件处理。
现在,我将整个项目一起编译成一个模块以简化导入。所有代码都驻留在编译成 hwmodule.pyd
文件的同一个 pyx 文件中。但是,为了实现跨平台编译的目标,我需要在安装时将几个小的 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')
从评论扩展而来的简短回答:这是 a feature that Cython supports。它允许您定义编译时间常量
DEF a = 5
并根据这些常量有条件地包含代码:
IF a==5:
cdef f():
return 1
ELSE:
cdef f():
return 2
它还定义了一些有用的常量:例如,UNAME_SYSNAME
让您可以在 Windows、OS X 和 Linux 之间进行选择。
这些表达式在您的 .pyx 文件上的 Cython 是 运行 时被评估 - 因此生成的 C 代码在 Windows 和 Linux 上是不同的,所以如果您想要要在另一个平台上编译,您需要重新运行 Cython,而不仅仅是重新编译 C 文件。
在 Cython 中没有 C #ifdef
/#ifndef
的直接等价物 - 测试是否定义了编译时间常量是 不 支持的功能。