10

Pythonから参照したいビットの#defineがたくさんあるCファイルがあります。それらは十分にあるので、Pythonコードにコピーしたくありません。代わりに、Pythonから直接それらを参照するための受け入れられたメソッドはありますか?

注:ヘッダーファイルを開いて解析するだけで簡単にできることはわかっていますが、もっとPython的な方法がある場合は、それを使用したいと思います。

編集:

これらは、マスク内のビットの意味を定義する非常に単純な#defineです。次に例を示します。

#define FOO_A 0x3
#define FOO_B 0x5
4

5 に答える 5

7

C .hファイルに#definesのみが含まれている(したがって、外部にリンクするものがない)という前提で実行すると、以下はswig 2.0(http://www.swig.org/)およびpython 2.7(テスト済み)で機能します。 )。上記のように、definesだけを含むファイルの名前がjust_defines.hであるとします。

#define FOO_A 0x3
#define FOO_B 0x5

それで:

swig -python -module just just_defines.h ## generates just_defines.py and just_defines_wrap.c
gcc -c -fpic just_defines_wrap.c -I/usr/include/python2.7 -I. ## creates just_defines_wrap.o
gcc -shared just_defines_wrap.o -o _just.so ## create _just.so, goes with just_defines.py

使用法:

$ python 
Python 2.7.3 (default, Aug  1 2012, 05:16:07) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import just
>>> dir(just)
['FOO_A', 'FOO_B', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_just', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic']
>>> just.FOO_A
3
>>> just.FOO_B
5
>>> 

.hファイルにエントリポイントも含まれている場合は、それらのエントリポイントを解決するために、いくつかのライブラリ(またはそれ以上)に対してリンクする必要があります。正しいライブラリを探す必要があるかもしれないので、それは解決策をもう少し複雑にします。しかし、「ケースを定義するだけ」の場合、これについて心配する必要はありません。

于 2012-08-27T18:53:37.157 に答える
7

Pythonソースtarballh2py.pyのディレクトリにあるスクリプトで運が良かったかもしれません。Tools/scripts複雑なプリプロセッサマクロを処理することはできませんが、ニーズには十分な場合があります。

スクリプトの先頭から機能について説明します。

#defineを読み、Pythonコードに変換します。#includeステートメントを処理します。1つの引数で#defineマクロを処理します。認識されない、または有効なPythonに変換されないものはすべて無視されます。

ファイル名引数がない場合、フィルターとして機能します。1つ以上のファイル名が指定されている場合、出力はローカルディレクトリ内の対応するファイル名に書き込まれ、すべて大文字に変換され、拡張子は「.py」に置き換えられます。

「-iregular_expression」の形式の1つ以上のオプションを渡すことにより、無視する追加の文字列を指定できます。これは、たとえばu_longへのキャストを無視する場合に便利です。単に「-i'(u_long)'」を指定します。

于 2012-08-28T04:38:10.270 に答える
1

#definesはマクロであり、Cコンパイラのプリプロセッサ以外では何の意味もありません。このように、彼らはどこでも多言語プログラマーの悩みの種です。(たとえば、このAdaの質問:2週間前のLinuxカーネルでのモジュールのライセンスの設定を参照してください)。

Cプリプロセッサを介してソースコードを実行する以外に、それらを処理する良い方法は実際にはありません。私は通常、彼らが何を評価するかを理解し(複雑な場合、実際にコンパイルして実行するよりも良い方法はないことがよくあります!)、その値をプログラムにハードコーディングします。

(よくある)厄介な部分は、CプリプロセッサがCコーダーによって、考え直さなくてもよく使用される非常に単純な小さなものであると見なされていることです。その結果、相互運用性に大きな問題を引き起こすことにショックを受ける傾向がありますが、Cが私たちに投げかける他のほとんどの問題にはかなり簡単に対処できます。

上に示した単純なケースでは、これを処理する最も簡単な方法は、Pythonプログラムのどこかにある定数に同じ2つの値をエンコードすることです。変更に対応することが重要な場合は、ファイルからこれらの値を解析するPythonプログラムを作成するのはそれほど問題ではないでしょう。ただし、Cコードはコンパイル時にこれらの値を再評価するだけであり、Pythonプログラムは実行するたびに再評価することを理解する必要があります(したがって、おそらくCコードもコンパイルされるときにのみ実行する必要があります)。

于 2012-08-27T18:29:36.787 に答える
1

拡張モジュールを作成している場合は、http://docs.python.org/3/c-api/module.html#PyModule_AddIntMacroを使用してください

于 2014-03-04T22:12:45.797 に答える
0

私はほぼ同じ問題を抱えていたので、Cファイルを解析するPythonスクリプトを作成しました。これは、cファイルに一致するように名前を変更し(ただし、.hではなく.pyを使用)、Pythonモジュールとしてインポートすることを目的としています。

コード:https ://gist.github.com/camlee/3bf869a5bf39ac5954fdaabbe6a3f437

例:

configuration.h

#define VERBOSE 3
#define DEBUG 1
#ifdef DEBUG
    #define DEBUG_FILE "debug.log"
#else
    #define NOT_DEBUGGING 1
#endif

Pythonからの使用:

>>> import configuration
>>> print("The verbosity level is %s" % configuration.VERBOSE)
The verbosity level is 3
>>> configuration.DEBUG_FILE
'"debug.log"'
>>> configuration.NOT_DEBUGGING is None
True
于 2016-09-13T05:51:06.070 に答える