C++ソースファイルとPythonソースファイルがあります。C++ソースファイルでPythonソースファイルの内容を使用できるようにしたいと思います。大きな文字列リテラルとして。次のようなことができます。
char* python_code = "
#include "script.py"
"
ただし、各行の最後に\を付ける必要があるため、これは機能しません。 Pythonコードの内容を手動でコピーして貼り付け、各行を引用符と終了\ nで囲むことはできますが、それは醜いです。python =ソースは効果的にC++アプリにコンパイルされます。より整理されており、エディターとの連携が優れているため、別のファイルに保存したいと思います(emacsはそれを認識するほど賢くありません[〜 #〜] c [〜#〜]文字列リテラルはpythonコードで、中にいる間にpythonモード)に切り替えます)。
私がPyRun_Fileを使用することを提案しないでください、それは私が最初に避けようとしていることです;)
C/C++プリプロセッサはトークンの単位で動作し、文字列リテラルはsingleトークンです。そのため、そのような文字列リテラルの途中に介入することはできません。
Script.pyを次のようなものに前処理できます。
"some code\n"
"some more code that will be appended\n"
ただし、#includeはそれです。または、 xxd
-i
を使用して、含める準備ができているC静的配列を生成できます。
これはあなたをそこまで到達させることはできませんが、それはあなたをかなり近づけるでしょう。
script.py
これが含まれています:
print "The current CPU time in seconds is: ", time.clock()
まず、次のようにまとめます。
STRINGIFY(print "The current CPU time in seconds is: ", time.clock())
次に、それを含める直前に、次のようにします。
#define STRINGIFY(x) #x
const char * script_py =
#include "script.py"
;
それよりももっと厳しい答えがあるかもしれませんが、私はまだ探しています。
このようなことを行う最良の方法は、環境/ツールセットにその機能がある場合、ファイルをリソースとして含めることです。
そうでない場合(組み込みシステムなど)、bin2cユーティリティ( http://stud3.tuwien.ac.at/~e0025274/bin2c/bin2c.c など)を使用できます。ファイルのバイナリ表現を取得し、そのデータに初期化されたバイトの配列を含むCソースファイルを吐き出します。配列を「\ 0」で終了させたい場合は、ツールまたは出力ファイルを微調整する必要があるかもしれません。
Bin2cユーティリティの実行をmakefileに組み込みます(または、ビルドの駆動に使用しているもののビルド前のステップとして)。次に、ファイルをコンパイルしてアプリケーションにリンクするだけで、文字列(またはファイルの他の画像)を配列で表されるメモリのチャンクに配置できます。
テキストファイルを文字列として含める場合、行末が関数が期待するものと一致しない可能性があることに注意する必要があります。これは、bin2cユーティリティに追加したい、または必要な別のことかもしれません。コードがファイル内の行末を正しく処理することを確認します。たぶん、bin2cユーティリティを変更して、テキストファイルを文字列として組み込むことを示す「-s」スイッチを設定します。これにより、行末が正規化され、配列の最後にゼロバイトが配置されます。
Pythonコードで、ダブルクォート、バックスラッシュ、トリグラフ、および場合によっては他のものに表示されるものを処理するために、独自の処理を行う必要があります。あなた同時に、改行を\ nに変換(またはバックスラッシュエスケープ)して、両端に二重引用符を追加できます。結果は、Pythonソースファイル、これを#includeできます。ビルドプロセスを使用してこれを自動化し、PythonソースをPythonとして編集できるようにします。
ビルドプロセスの一部として Cog を使用できます(前処理を実行し、コードを埋め込むため)。この結果はおそらく理想的ではないことを認めます。それ以降、両方の場所にコードが表示されることになります。しかし、「Python」、「C++」、「プリプロセッサ」を間近で見るときはいつでも、言及する価値があると感じています。