search
LoginSignup
18
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

Emscriptenでファイルを読み込むソースをJavaScriptに変換するには

背景

OpenGLなソースをEmscriptenでJavaScriptに変換できることは分かったのだが、
OpenGLなソースだとテクスチャーをファイルとして読み込むようなケースが多々ある、
Emscriptenでこういったファイルの読み込みも可能なような記述があるが、
具体的な方法が英語力の低さから分からずにいた。

そんな折、はてなの人力検索ですばらしい質問と回答を発見して、これを手がかりに
C++でファイルを読み込むプログラムをEmscriptenでJavaScriptに変換することが出来た。

前提

EmscriptenでJavaScriptに変換された本体のプログラムのファイルアクセスは仮想ファイルシステムを介して行われる。

この為、本体のプログラムを実行する前に、この仮想ファイルシステムに必要なファイルやフォルダの登録が必要となる模様。

emscriptenのページでは自動でやってくれるやり方もあるようだが、このやり方だと、ファイルの内容がコンパイル時に埋め込まれてします。(まぁ、別ファイルにできるので、こちらを後から変更できそうだが。。)

C/C++のソース中でファイル名を指定して読んでいる場合、
FS.createPreloadedFileを使うと対応できる。

また、前処理内で、動的にデータを作成してしまうAPIも用意されている模様。

対象のファイルはemccを実行するディレクトリを
/としてJavaScript側では扱われる模様
(絶対パス指定ならそのままのパスで扱われる模様)

同名ファイルでフォルダが違うファイルを読み込むサンプル

C++のソース

#include <fstream>
#include <iostream>

using namespace std;

int
main (int argc, char **argv)
{
  string line;
  ifstream fin ("./input.txt");
  while (getline (fin, line))
    {
      cout << line << endl;
    }
  fin.close ();
  fin.open ("data/input.txt");
  while (getline (fin, line))
    {
      cout << line << endl;
    }
  fin.close ();

  return 0;
}

前処理用のJavaScriptソースの準備

前処理のJavaScriptでやり事は以下

  • 仮想ファイルシステムにフォルダを登録
  • 仮想ファイルシステムにファイルを登録

前処理用のJavaScript

pre.js
Module['preRun'] = function () {
    FS.createFolder(
        '/', // 親フォルダの指定
        'data', // フォルダ名
        true, // 読み込み許可
        true // 書き込み許可(今回の例はfalseでもよさげ)
    );
    FS.createPreloadedFile(
        '/', // 親フォルダの指定
        'input.txt', // ソース中でのファイル名
        '/input.txt', // httpでアクセスする際のURLを指定
        true, // 読み込み許可
        false // 書き込み許可
    );
    FS.createPreloadedFile(
        '/data',
        'input.txt',
        '/data/input.txt',  // httpでアクセスする際のURLを指定
        true,
        false
    );
};

--pre-jsを指定してhtmlファイルを作成

emcc target.cpp -o target.html --pre-js pre.js

読み込まれるファイルの用意

echo "hogehoge" > input.txt
mkdir data
echo "foobar">data/input.txt

HTTPサーバを立てる

python -m SimpleHTTPServer 8000

ブラウザでアクセスしてみる

まとめ

仮想フォルダを準備するというのにちょっと躓きましたが、
思ったより、やってみると簡単だった。はてな人力質問の質問者様、回答者様に感謝です。

以上、ファイルの読み込みのあるCやC++をEmscriptenでJavaScriptに変換する方法でした。

関連記事

Link

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
18
Help us understand the problem. What are the problem?