2013-10-28 12 views
14

コンパイル時に文字列にファイルを読み込み、道に似たコンパイル時、で私のプログラムに文字列としてそれを含める#includeそれを行います。</em>(のは<code>foo.cpp</code>それを呼びましょう)私は、ファイル<em>で何かを書きたい

今、私はこのCプリプロセッサ#define使用しています。この例のように使用する文字列にコードの束を変換する

#define toString(src) #src 

を:

const char* str = toString(
    int x; 
    void main(){} 
); 

あなたはマクロについて読むことができますあなたが望むならば、ストリング化there

私はこのコードをコンパイル時に "リンク"される外部ファイルに移動したいと思います。 ファイルをプログラムと一緒に配布する必要はありません。実行時に読み込む場合にはそうです。

は、私は以下に示すように#includeディレクティブを使用しようとしましたが、コンパイラはそれを拒否した:

const char* str = toString(
#include "foo.cpp" 
); 

g++は完全に混乱しているようだが、clang++は私に、このエラーが発生しました:

error: embedding a #include directive within macro arguments is not supported 

これを行うことができるかどうか誰にも分かりますか?

注:私はこの情報が何らかの用途に使用されているとは考えていますが、これを使用してGLSLシェーダーを作成しています。

PS:(。例えばxxd)あなたは、これは、独自のファイルに巨大な文字列で私のコードを入れて、this questionの複製であるか、外部ツールを使用して教えてくださいする前にその16進数表現をダンプするには、「解決策」ではありません私のために、私の現在の方法よりも優れていない(すなわち、より簡単で清潔な)ので。


数年後に更新、:
私はちょうど私がそれを重複として閉鎖されたとして、この質問に答えるためにやったことがなかった実現。 a comment on this articleに基づいて、私がthis commitを見て、それ以来それを使用していたときに私が探していた答えが見つかりました。一言で言えば

、小さなアセンブリファイルは、あなたがしたいファイルが含まれており、三つの変数NAME_beginNAME_endNAME_lenは、あなたのCコードからその内容にアクセスできるようにして、与えられたNAMEの下でそれらを公開します。

この方法では、必要なコードだけを含む通常のファイルがあり、実行時に読み込むか、xxdのフープをジャンプする必要はなく、コンパイル時に自動的に読み込まれます。

+4

リンクされた質問の複製です。あなたは提供された回答のどれも好きではありません。しかし答えは、あなたがそれをやりたいやり方で行うことができないということです。そのため、リンクされた質問の答えを反映するたくさんの回答を得るだ​​けです。 – rici

+0

どのプラットフォームをコンパイルしようとしていますか...それともクロスプラットフォームにしようとしていますか? –

+0

私は、「より良い」、「より簡単な」、「よりクリーンな」という用語が* this *メソッドにどのように適用されるかを見極めようとしています。理解のためだけに、ソースレベルの変数セットに前処理して、目に見えないコードを使用してファイルに書き込んだ後、ソースからそのファイルをコンパイルして、問題が発生しているステップ1の "ソース"にプリプロセッサステートメントを埋め込む? – WhozCraig

答えて

10

私はあなたが達成しようとしているものはかなりわかりませんが、しかし、Linuxのコマンドラインユーティリティxxdは、あなたが探しているものかもしれ:

xxd -i [filename] 

あなたのファイルを持つ配列を含むCスタイルのヘッダファイルを生成しますフルバイナリエンコーディングの内容とその長さの変数

例:

xxd -i /proc/cpuinfo 

は、あなたがあなたのコードが得られ、ヘッダーが含まれており、これらの変数を経由して配列し、ファイルの長さにアクセスすることができ

unsigned char _proc_cpuinfo[] = { 
    0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x09, 0x3a, 0x20, 
    0x30, 0x0a, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x09, 
... 
}; 
unsigned int _proc_cpuinfo_len = 654390; 

でファイルを作成します。

+3

私がこの質問で言ったように、この解決策は私の現在の方法よりは簡単ではありません*(主観的です)*ですが、コピー/ペーストのためにありがとう:) – 1ace

7

あなたはxxdが好きではないと言っていますが、それはファイルを読むことができないためです。けっこうだ。文字列を入出力としたいので、データを別の形式でエンコードする独自のユーティリティを書くのは簡単でしょう。文字列リテラルの連結を利用して、これを簡単に読みやすくすることができます。

const char* str = 
#include "foo.h" 
    ; 

がfoo.h:

" int x;" "\n" 
" void main(){}" "\n" 

私は簡単に任意の再フォーマットせずにファイルを使用して許可されているだろうが、それはうまくいきませんでしたC++ 11のraw string literalsを、使用してみました。 #includeは、必要に応じてファイルを含めるのではなく、文字列の一部と見なされます。

1

この場合、最も簡単なのは、ファイルを読み取る小さな プリプロセッサを書き、各行を引用符で囲んで という文字列を出力して出力します。私はおそらくPythonでこれを行うだろうが、それは であり、C++でもまっすぐである。

void 
wrapFile(std::istream& inputFile, 
      std::ostream& outputFile, 
      std::string const& variableName) 
{ 
    outputFile << "extern char const " << variableName << "[] =\n"; 
    std::string line; 
    while (std::getline(inputFile, line)) { 
     outputFile << " \"" << line << "\\n\"\n"; 
    } 
    std::outputFile << ";" << std::endl; 
} 

あなたが「ファイルにある内容に応じて:あなたは は どこか(おそらくargvからinputFileoutputFilevariableNameを持っていますが、入力ファイル名から 後者の二つを導出することがありますと仮定すると含む再、あなたは "または\のようなものを 逃れるために、それを出力する前にlineをマングルする必要がある場合があります。

あなたは空想取得したい場合は、追加することができます 最後にラップされた行にセミコロンを挿入するテストがありますが、それは実際には必要ありませんが、 の行ではありません。

これは、'\0'終了文字列になります。文字列の そうな長さを考えると、長さ を二変数を追加することが好ましいかもしれない:

std::outputFile << "extern int const " 
       << variableName 
       << "_len = sizeof(" << variableName << ") - 1;\n"; 

(あなたが 終端をカウントしたくないので、-1を忘れてはいけません'\0'コンパイラが文字列 リテラルに追加することを示します。あなたがそれを使用すること ます生成されたファイルを含めている場合)、あなたは必ずしもstd::begin以来、これを必要としないと std::endは、必要な情報を提供します(しかし、再び、 は を無視し、std::end(variableName) - 1を使用することを忘れないでください'\n')。

あなたがmakeを使用している場合、それはあなたの生成 ファイルを作るためにかなり簡単です包まれているファイルに依存し、などラッピング(これは上記のソース に依存して、実行可能なん )。 Visual Studioでは、コードを (これはPythonを使用する理由の1つ)で書くと、 という別のラッピングコードのプロジェクトを作成する必要があります。 にはいくつかの問題があります依存関係管理; Visual Studio は実際にプロの作業用に設計されていません(このようなテクニックを使用して大規模なブロック が定期的に生成されます)。

+0

VSを使用すると、リソースにアクセスし、LoadResource関数を使用してアクセスします。それはWindows固有のものです。 –

+0

@ZacHowlandはい。 Windowsにはいくつかのオプションがあります。残念ながら、それほど移植性がありません。 –

+0

悲しいことに。私のコメントは、Visual Studioは実際に専門的な作業のために設計されていないという考え方に基づいていました。それは...ですが、それはWindows特有のプロフェッショナルワークに焦点を当てています(ただし、オープンソースの新しい分野での変化が見られるかもしれません)。 –

関連する問題

 関連する問題