人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

ファイルを読み込むC言語のプログラムをemscriptenでjavascriptに変換して
ブラウザからローカルファイルを、このスクリプトに読み込ませて、処理を実行する。
この具体例を示してください。

外部ファイル読み込みを行うサンプルソースはあるのですが、
ローカルファイルを読ませる例はないようなのですが

●質問者: tak
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● ukyoweb
●170ポイント ベストアンサー

パスを指定したデータ読み込みに関しては以下URLが参考になります。
http://mozakai.blogspot.jp/2012/03/howto-port-cc-library-to-javascript.html

もしも、C側のプログラムが標準入力からファイルを読み込むように作ってある場合以下を。
https://github.com/kripken/lzma.js

で、ローカルファイルを読み込むにはFileReaderを使うとよいかと思います。ファイルはinput要素やドラッグ&ドロップで取得できます。

var reader = new FileReader;
reader.readAsArrayBuffer(file);
reader.onload = function() {
fnExportedWithEmscripten(new Uint8Array(reader.result));
};


takさんのコメント
すみませんもう少し説明お願いします。 例えば、Cの側で 引数としてファイル名や、FILE * などを関数に渡す場合、 どうなるのでしょうか。 特にjsファイル中で function _main()などを 具体的にどうやって呼ぶのかなど

ukyowebさんのコメント
例えば<code>input</code>という名前のファイルを読み込み、<code>output</code>という名前のファイルを吐き出すプログラムがあってCUIのインターフェースが以下のような感じだったとします。 <pre>hoge input output</pre> で、これをJSのプログラム内では以下のように使うようにしたいとします。 <pre>var output = hoge(input); // arrayで渡してarrayで返す</pre> 1.まずは、main関数が呼ばれる前に前処理をする関数(JS側で)を作ります。これをpre.jsとします。 参照(https://github.com/kripken/emscripten/wiki/Filesystem-Guide) <pre>Module['preRun'] = function() { FS.createDataFile( '/', 'input', Module['input'], true, true); FS.createDataFile( '/', 'output', null, true, true); }; Module['arguments'] = ['input', 'output']; Module['getOutput'] = function() { return FS.findObject("/output").contents; }; };</pre> 2.コンパイルします。 <pre>emcc -O2 hoge.c -o hoge.raw.js --pre-js pre.js</pre> 3.コンパイルしたファイル(hoge.raw.js)はそのままでは使えません。以下のような感じでラップして初めて使えるようになります。 <pre>function hoge(input) { var Module = { input: input }; // hoge.raw.jsの中身 return Module.getOutput(); }</pre> わかりましたでしょうか。CUI系は大体このパターンでいけます。例えば、インターフェースが以下のような場合、 <pre>fuga -i input -o outpu</pre> pre.js内のModule['arguments']を <pre>Module['arguments'] = ['-i', 'input', '-o', 'output'];</pre> のような感じにすればOKです。 あと、もしも<code>_main</code>がどのように呼ばれているか知りたい場合はemscriptenのコンパイルオプションに<code>--closure 0</code>を付けるとClosure Compilerの圧縮が行われないので見やすくなります(コード量は多くなる)。

takさんのコメント
申し訳ありません。ここまでのコメントの内容は質問前にすでに理解しています。 このinputとは、ファイルのパスなのでしょうか? それが全くわからないのですが、絶対パスで指定したり、htmlファイルと同一ディレクトリのファイルを指定しても読めないようなのですが これで、例えばFileReaderで仮想ファイルシステムにファイルをコピーすれば、 読み取れるようになるということなのでしょうか

ukyowebさんのコメント
1. inputについて <code>input</code>は<code>./input</code>です。 2. ファイル読み込みについて 事前に準備してある外部ファイルを読み込むということでしょうか。 それでしたら<code>FS.createPreloadedFile</code>を使うとHMLHttpRequestでよしなに読み込んでくれます。 ローカルで試す場合は、鯖(<code>python -m SimpleHTTPServer</code>とか)を立ててください。 例: pre.js <pre>Module['preRun'] = function() { FS.createPreloadedFile( '/', 'input.txt', 'path/to/input.txt', // 適宜読み替えてください true, false ); };</pre> example.cpp <pre>#include <fstream> #include <iostream> using namespace std; int main() { char ch; ifstream fin("input.txt"); while(!fin.eof()) { fin >> ch; cout << ch; } fin.close(); return 0; }</pre> コンパイル(表示を確認するだけなので直接htmlにコンパイルします)。 <pre>emcc example.cpp -o example.html --pre-js pre.js</pre>

takさんのコメント
この例を実際にやってみると、出力つまり &lt;textarea class="emscripten" id="output" rows="8"&gt; &lt;/textarea&gt; の中には input.txtの内容ではなく、 path/to/input.txt とだけ出力されるのですが 何がおかしいのでしょうか? このファイルパスが具体的にどうすればいいのかわかりません。 'path/to/input.txt', // 適宜読み替えてください この適宜とは、具体的にどのようなファイル構成だったら具体的にどのように替えればよいのでしょうか? また、 事前に準備してある外部ファイルを読み込むのではなく、 最終的にはあくまで、 &lt;INPUT type="file" などでローカルファイルを読み込みたいです。

takさんのコメント
実際に期待通りに動く実例の完全なソースを見たいのです。 web上で そのような"完全"な"実例"を見つけられなかったので

ukyowebさんのコメント
まず、ファイルパスについては、path/to/input.txtのinput.txtがexample.htmlと同じディレクトリにあるのなら./input.txtとかにしてください。という話です。 input要素の詳細についてはググってください。 あと、"実際に期待通りに動く実例の完全なソース"は以下を参照してください。 https://github.com/ukyo/zlib-asm/ http://ukyo.github.io/zlib-asm/bench-asm.html ちなみに、ローカルで試すときは鯖を立ててくださいね。でないと、FileReader関係でセキュリティ的なエラーが出ます。

takさんのコメント
zlibなど外部のリソースを一切使わない 完全にプリミティブなソースが良いのです。 http://hujimi.seesaa.net/article/264965970.html 例えば、このfile.jsを呼ぶ完全なhtmlファイルなどが見たいです

ukyowebさんのコメント
多分、takさんが知りたいことはemscriptenじゃなくてFileReaderの使い方だと思うんですよ。 ローカルファイルの読み込みについては以下がかなり参考になるので読んでみてください。 http://www.html5rocks.com/ja/tutorials/file/dndfiles/ 完全なHTMLの例: https://gist.github.com/ukyo/5494035

takさんのコメント
すみません。やっぱり、期待通りの結果が得られません。 http://ukyo.github.io/zlib-asm/bench-asm.html などは、htmlとjsファイルとをコピーしてサーバ上で同じ挙動が再現できるのですが https://gist.github.com/ukyo/5494035 これについては、何も結果が返ってきません。 確認させていただきたいのですが、file.jsのサイズは 87122バイトでしょうか?

ukyowebさんのコメント
すみません、ミスってました。fileio is not defined的なエラー出ませんでした? 直したのでこれで動くと思います。file.jsについてもあとでgistにファイルを追加します。 ファイルサイズもそのとき確認します。

takさんのコメント
TypeError: data is null @ file.js:1092 です。 今現在の、 fleio.html でそれです。 file.jsの方の問題だと思うんですが

takさんのコメント
emcc -v で emcc (Emscripten GCC-like replacement + linker emulating GNU ld ) 2.0 clang version 3.0 (tags/RELEASE_30/final) Target: x86_64-unknown-linux-gnu Thread model: posix です

ukyowebさんのコメント
終了しちゃいました? outputの方は現在のemscriptenだとnullの部分を空配列にすると正しく実行できるようです。 それと、htmlの方もfileioに渡す引数をnew Uint8Array(reader.result)にしてあげないとダメでしたね。 サンプルのほうはgithubにまとめましたのでそちらで。 https://github.com/ukyo/emscripten-fileio

takさんのコメント
なぜ、出来ないのか、 実行するために必要な事が何であるのか洗い出せました。 ありがとうございます。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ