Вопрос по ctypes, header, constants, c, python – Импортировать константы из файла .h в python

15

я искал простой ответ на этот вопрос, но, похоже, я могунайти его. Я предпочел бы держаться подальше от любых внешних библиотек, которые неt уже включен в 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 
#include 
#include "constants_a.h"

// do some calculations, blah blah blah

Как я могу импортировать константы из файла заголовка в класс Python?

Причина для заголовочных файлов constants_a.h и constants_b.h заключается в том, что я использую python для выполнения большинства вычислений с использованием констант, но в какой-то момент мне нужно использовать C для более оптимизированных вычислений. На данный момент я использую ctypes, чтобы обернуть код c в Python. Я хочу держать константы подальше от кода на тот случай, если мне понадобится обновить или изменить их, а также сделать мой код намного чище. Я неНе знаю, поможет ли это отметить, что я также использую NumPy, но кроме этого, нет других нестандартных расширений Python. Я также открыт для любых предложений относительно дизайна или архитектуры этой программы.

Извините за столь поздний отзыв всем. У меня был новый, срочный проект, над которым я работал, и я должен был отложить это на второй план. На данный момент я застрял между Конги Эмилиос ответами. Я, вероятно, буду больше склоняться к КонгуРеализация ctypes, но мне все еще очень нравится метод синтаксического анализа, использующийre, Спасибо всем за отличные идеи! Manila Thrilla

Ваш Ответ

4   ответа
1

Хотя вы просили избегать других нестандартных библиотек, вы можете взглянуть на Cython (Cython: C-Extensions for Python www.cython.org/), который предлагает гибкость кодирования Python и грубую скорость выполнения. C / C ++ - скомпилированный код.

Таким образом, вы можете использовать обычный Python для всего, но обрабатывать дорогие элементы кода, используя его встроенные C-типы. Затем вы можете также преобразовать ваш код Python в файлы .c (или просто обернуть внешние библиотеки C), которые затем можно скомпилировать в двоичный файл. Я'мы добились до 10-кратного ускорения, выполняя это для числовых процедур. Я также считаю, что NumPy использует его.

Ну, изначально я реализовал свой код на Cython, но, как я уже говорил в своем вопросе, сейчас я использую ctypes для поддержки переносимости. Проблема в том, что Cython недоступен в стандартной библиотеке Python, но ctypes есть. Но ты'Правильно, Cython потрясающий и очень простой в использовании. Я нашел ctypes на несколько микросекунд быстрее, чем Cython. Manila Thrilla
11

re модуль), чтобы разобрать информацию, которую вы хотите из файлов.

Создание полного синтаксического анализатора C было бы огромным, но если вы используете только переменные, а файл достаточно простой / предсказуемый / под контролем, то то, что вам нужно написать, просто.

Просто остерегайтесьПопался' артефакты, такие как закомментированный код!

Посмотрите наИнструменты / Scripts / h2py.py Сценарий, переработанный с 1992 года. eryksun
Я на самом деле использовал эту реализацию, а не Cong 's. Я обнаружил, что это немного более адаптивно к изменению / добавлению констант и параметров. Поэтому я выбрал это как лучший ответ сейчас. Manila Thrilla
@ManilaThrilla: Добро пожаловать. Я прочитал и проголосовал Cong 'Ответ, это очень информативно. Так как лучший ответ вряд ли появится после всего этого времени, я предлагаю вам отметить Конгкак принято. Emilio M Bumachar
Спасибо Эмилио и Эриксун. Пока я не увидел Конгответ, я верил, что это был путь. Для этого было бы неплохо написать небольшой парсер. Manila Thrilla
15

определяющий переменные в заголовочном файле C плохого стиля. Заголовочный файл должен толькообъявлять объекты, оставляя их определения для соответствующих.c» файл исходного кода.

Одна вещь, которую вы можете сделать, это объявить глобальные константы библиотеки какextern const whatever_type_t foo; и определить (или "воплощать в жизнь") их (т.е. присвоение им значений) где-то в вашем коде C (убедитесь, что вы делаете это только один раз).

Во всяком случае, давайтес игнорироватькак ты делаешь это. Просто предположим, что вымы уже определили константы и сделали их символы видимыми в вашем общем объектном файле "libfoo.so», Допустим, вы хотите получить доступ к символуpi, определяется какextern const double pi = 3.1415926; в libfoo, из вашего кода Python.

Теперь вы обычно загружаете свой объектный файл в Python, используяctypes как это:

>>> 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_view для того, чтобы использовать значениеpi? Вы отбрасываете это какconst double * и разыменовывать это.*(const double *)(pi_view)

Так что это все очень неловко. Может я'м чего-то не хватает, но я считаю, что это дизайнctypes модуль - этотам в основном для изготовлениявызовы внешних функцийне для доступа "иностранный» данные. И экспорт чистого символа данных в загружаемую библиотеку, возможно, встречается редко.

И это не будет работать, если константы являются только определениями макросов C. Там'Как правило, вы никак не можете получить доступ к макроопределенным данным извне. Oни'повторно раскрывается во время компиляции, не оставляя видимых символов в сгенерированном файле библиотеки,если вы также экспортируете их значения макросов в ваш C-код.

Спасибо Конг за ваш очень подробный ответ. Я думаю, что доступ к значениям экземпляров будет подходящим для моей работы. Это'это скорее научная попытка, чем фактический выпуск программного обеспечения, поэтому яеду для простоты и ясности. Мне любопытно, однако, что вы бы посчитали лучшим стилем для определения констант. Имейте в виду, что эти константы должны находиться в отдельном файле, чтобы можно было быстро редактировать или изменять их значения. Manila Thrilla
Ну, я только что обнаружил неуклюжий способ сделать это:python.net/crew/theller/ctypes/...  Ты можешь попробоватьpi = ctypes.c_double(libfoo, "pi") в коде Python; это возвращаетctypes.c_double экземпляр, и вы можете получить доступ к его значению с помощью.pi.value Cong Ma
2

читаемый программами на Python и C, вместо того, чтобы хранить постоянные значения в заголовках. Например. простой CSV, INI-файл, или даже ваш собственный простой форматключ: значение» пар. И вам не нужно будет перекомпилировать программу C каждый раз, когда выЯ хотел бы изменить одно из значений :)

Это звучит здорово, но я думаю, что тогда мне придется либо создать парсер для программы на C, но я нене хочу делать, или использовать библиотеку, как LibConfig, что я также не хочу делать. Было бы неплохо, однако, не перекомпилировать программу на Си каждый раз. Возможно, у вас есть пример для этого файла конфигурации? Manila Thrilla
Конфигурация в формате JSON в качестве примера. Поддерживается Pythons стандартная библиотека и множество реализаций для C доступны наjson.orgI» Zaur Nasibov

Похожие вопросы