gpt4 book ai didi

python - 将 .h 文件中的常量导入 python

转载 作者:太空狗 更新时间:2023-10-29 17:02:35 24 4
gpt4 key购买 nike

我一直在寻找这个问题的简单答案,但似乎找不到。我宁愿远离任何尚未包含在 Python 2.6/2.7 中的外部库。

我有 2 个类似于以下内容的 c 头文件:

//constants_a.h
const double constant1 = 2.25;
const double constant2 = -0.173;
const int constant3 = 13;

...

//constants_b.h
const double constant1 = 123.25;
const double constant2 = -0.12373;
const int constant3 = 14;

...

我有一个 python 类,我想将这些常量导入到:

#pythonclass.py
class MyObject(object):
def __init(self, mode):
if mode is "a":
# import from constants_a.h, like:
# self.constant1 = constant1
# self.constant2 = constant2
elif mode is "b":
# import from constants_b.h, like:
# self.constant1 = constant1
# self.constant2 = constant2

...

我也有使用常量的 C 代码,类似于:

//computations.c
#include <stdio.h>
#include <math.h>
#include "constants_a.h"

// do some calculations, blah blah blah

如何将头文件中的常量导入到 Python 类中?

头文件 constants_a.h 和 constants_b.h 的原因是我使用 python 进行大部分使用常量的计算,但在某一时刻我需要使用 C 来进行更优化的计算。此时我正在使用 ctypes 将 c 代码包装到 Python 中。我想让常量远离代码,以防万一我需要更新或更改它们,并使我的代码更清晰。我不知道是否有助于注意我也在使用 NumPy,但除此之外,没有其他非标准 Python 扩展。我也乐于接受有关此程序的设计或架构的任何建议。

最佳答案

一般来说,在 C 头文件中定义变量是一种糟糕的风格。头文件应该只声明对象,将它们的定义留给适当的“.c”源代码文件。

你可能想要做的一件事是声明库全局常量,如 extern const whatever_type_t foo; 并在你的某个地方定义(或“实现”)它们(即给它们赋值) C 代码(确保只执行一次)。

无论如何,让我们忽略您是如何做的。假设您已经定义了常量并使它们的符号在您的共享对象文件“libfoo.so”中可见。假设您要从您的 Python 代码访问符号 pi,在 libfoo 中定义为 extern const double pi = 3.1415926;

现在您通常使用 ctypes 在 Python 中加载目标文件,如下所示:

>>> import ctypes
>>> libfoo = ctypes.CDLL("path/to/libfoo.so")

但是你会看到 ctypes 认为 libfoo.pi 是一个函数,而不是常量数据的符号!

>>> libfoo.pi
<_FuncPtr object at 0x1c9c6d0>

要访问它的值,您必须做一些相当笨拙的事情——将 ctypes 认为是函数的转换回到一个数字。

>>> pi = ctypes.cast(foo.pi, ctypes.POINTER(ctypes.c_double))
>>> pi.contents.value
3.1415926

在 C 术语中,这模糊地对应于发生的以下事情:你有一个 const double pi,但有人强制你只能通过函数指针使用它:

typedef int (*view_anything_as_a_function_t)(void);
view_anyting_as_a_function_t pi_view = &pi;

为了使用 pi 的值,您如何处理指针 pi_view?您将它转换回 const double * 并取消引用它:*(const double *)(pi_view)

所以这一切都很尴尬。也许我遗漏了一些东西,但我相信这是 ctypes 模块的设计 —— 它主要用于进行外部函数调用,而不是用于访问“外部”数据。在可加载库中导出纯数据符号可以说是很少见的。

如果常量只是 C 宏定义,这将不起作用。通常您无法从外部访问宏定义的数据。它们在编译时进行宏扩展,在生成的库文件中不留下任何可见符号,除非您还在 C 代码中导出它们的宏值。

关于python - 将 .h 文件中的常量导入 python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15293604/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com