Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
18
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
18
Help us understand the problem. What are the problem?