preamble.js

preamble.js の JavaScript API は、コンパイルされた C コードと対話するためのプログラミングアクセスを提供します。これには、コンパイルされた C 関数の呼び出し、メモリへのアクセス、ポインタの JavaScript Strings への変換および Strings からポインタへの変換(異なるエンコーディング/フォーマットを使用)、およびその他の便利な関数が含まれます。

Emscripten の出力 JS は、高いレベルでは、プリアンブル (src/preamble.js から)、次にコンパイルされたコード、そしてポストアンブルを含むため、これを「preamble.js」と呼びます。(もう少し詳しく説明すると、プリアンブルにはユーティリティ関数と設定が含まれ、ポストアンブルは接続を行い、アプリケーションの実行を処理します。)

プリアンブルコードは、出力 JS に含まれており、その後、コンパイラーによって、追加した --pre-js および --post-js ファイル、および JavaScript ライブラリ (--js-library) からのコードとともに、すべてまとめて最適化されます。つまり、プリアンブルからメソッドを直接呼び出すことができ、コンパイラーはそれらが必要であると認識し、未使用として削除することはありません。

HTML 上の別のスクリプトタグなど、コンパイラーが認識できない場所からプリアンブルメソッドを呼び出す場合は、それらを**エクスポート**する必要があります。そのためには、EXPORTED_RUNTIME_METHODS に追加します (例: -sEXPORTED_RUNTIME_METHODS=ccall,cwrapccallcwrap をエクスポートします)。エクスポートすると、Module オブジェクト (例: Module.ccall) でそれらにアクセスできます。

Module.ccall または別のランタイムメソッドをエクスポートせずに使用しようとすると、エラーが発生します。 -sASSERTIONS を使用したビルドでは、コンパイラーは、エクスポートする必要があることを説明する、役立つエラーメッセージを表示するコードを出力します。一般的に、何かおかしい場合は、アサーションを使用してビルドすると役立ちます。

JavaScript からコンパイルされた C 関数を呼び出す

ccall(ident, returnType, argTypes, args, opts)

JavaScript からコンパイルされた C 関数を呼び出します。

この関数は、JavaScript からコンパイルされた C 関数を実行し、結果を返します。C++ の名前修飾により、「通常の」C++ 関数を呼び出すことはできません。関数は、**.c** ファイルで定義するか、extern "C" で定義された C++ 関数にする必要があります。

returnTypeargTypes を使用すると、パラメーターの型と戻り値を指定できます。指定できる型は、"number""string""array"、または "boolean" です。これらは、適切な JavaScript の型に対応します。数値型または C ポインタには "number" を使用し、文字列を表す C char* には string を使用し、ブール型には "boolean" を使用し、8 ビット整数データを含む JavaScript 配列と型付き配列には "array" を使用します。つまり、データは 8 ビット整数の C 配列に書き込まれます。特に、ここで型付き配列を指定する場合は、Uint8Array または Int8Array である必要があります。別の型のデータの配列を受け取る場合は、手動でメモリを割り当てて書き込み、ここでポインタを提供できます (ポインタは単なる数値であるため、"number" として)。

// Call C from JavaScript
var result = Module.ccall('c_add', // name of C function
  'number', // return type
  ['number', 'number'], // argument types
  [10, 20]); // arguments

// result is 30

  • ccall は、一時的な値に C スタックを使用します。文字列を渡すと、呼び出しが完了するまでしか「有効」ではありません。呼び出されるコードが後で使用するためにポインターを保存する場合、無効なデータを指している可能性があります。

  • 文字列を永続的にする必要がある場合は、たとえば、_mallocstringToUTF8() を使用して作成できます。ただし、後で手動で削除する必要があります!

  • LLVM の最適化は、関数をインライン化して削除できます。その後、それらを呼び出すことができなくなります。同様に、Closure Compiler によって縮小された関数名にはアクセスできません。いずれの場合も、解決策は、emcc を呼び出すときに、関数を EXPORTED_FUNCTIONS リストに追加することです。

    -sEXPORTED_FUNCTIONS=_main,_myfunc"
    

    (main もエクスポートすることに注意してください。そうしないと、コンパイラーはそれが必要ないものと見なします。) エクスポートされた関数は、通常どおりに呼び出すことができます

    a_result = Module.ccall('myfunc', 'number', ['number'], [10])
    
引数
  • ident – 呼び出す C 関数の名前。

  • returnType – 関数の戻り値の型。array は、配列の長さを知る方法がないため、サポートされていないことに注意してください。void 関数の場合、これは null にすることができます (注: JavaScript の null 値であり、「null」という単語を含む文字列ではありません)。

64 ビット整数は、下位ビットと上位ビットの 2 つの 32 ビットパラメーターになります (64 ビット整数は JavaScript の数値で表現できないため)。

引数
  • argTypes – 関数の引数の型の配列 (引数がない場合は、省略できます)。

  • args – ( returnType と同じ) ネイティブ JavaScript 値としての関数の引数の配列。文字列引数はスタックに格納されることに注意してください (JavaScript 文字列はスタック上の C 文字列になります)。

戻り値

( returnType と同じ) ネイティブ JavaScript 値としての関数呼び出しの結果。または、async オプションが設定されている場合は、結果の JavaScript Promise。

Opts

オプションのオブジェクト (オプション)。次のプロパティを含めることができます

  • async: true の場合、ccall が非同期操作を実行することを示します。これは、asyncify サポートでビルドしていることを前提としています。

非同期呼び出しは、現在 Promise エラー処理をサポートしていません。

cwrap(ident, returnType, argTypes)

C 関数のネイティブ JavaScript ラッパーを返します。

これはccall()に似ていますが、必要な回数だけ再利用できるJavaScript関数を返します。C関数はCファイルで定義することも、extern "C"(名前マングリングを防ぐため)を使用して定義されたC互換のC++関数にすることもできます。

// Call C from JavaScript
var c_javascript_add = Module.cwrap('c_add', // name of C function
  'number', // return type
  ['number', 'number']); // argument types

// Call c_javascript_add normally
console.log(c_javascript_add(10, 20)); // 30
console.log(c_javascript_add(20, 30)); // 50

  • cwrapは一時的な値のためにCスタックを使用します。文字列を渡すと、呼び出しが完了するまでしか「有効」になりません。呼び出されるコードが後で使用するためにポインタを保存する場合、無効なデータを指す可能性があります。文字列を永続的に保持する必要がある場合は、たとえば、_mallocstringToUTF8()を使用して作成できます。ただし、後で手動で削除する必要があります。

  • 関数をラップするには、emccを呼び出すときに、関数をEXPORTED_FUNCTIONSリストに追加してエクスポートする必要があります。関数がエクスポートされていない場合、最適化によって削除される可能性があり、cwrapは実行時にそれを見つけることができません。(ASSERTIONSが有効になっているビルドでは、このような状況でcwrapがエラーを表示します。アサーションなしのリリースビルドでは、存在しない関数をラップしようとすると、undefinedを返すか、実際に呼び出されたときにエラーを返す関数を返すことによってエラーが発生します。これは、cwrapがどのように最適化されるかによって異なります。)

  • cwrapは実際にはコンパイルされたコードを呼び出しません(返されるラッパーを呼び出すだけです)。つまり、ランタイムが完全に初期化される前であっても、cwrapを早期に呼び出すことは安全です(ただし、返されるラップされた関数を呼び出すには、一般的にコンパイルされたコードを呼び出すのと同様に、ランタイムを待つ必要があります)。

    -sEXPORTED_FUNCTIONS=_main,_myfunc
    

    エクスポートされた関数は通常どおりに呼び出すことができます

    my_func = Module.cwrap('myfunc', 'number', ['number'])
    my_func(12)
    
引数
  • ident – 呼び出す C 関数の名前。

  • returnType – 関数の戻り値の型。これは、適切なJavaScript型に対応する"number""string"、または"array"(任意のCポインタには"number"を使用し、JavaScript配列および型付き配列には"array"を使用します。配列は8ビットであることに注意してください)にすることができます。または、void関数の場合は、nullにすることができます(注:文字列 "null" を含む文字列ではなく、JavaScriptのnull値)。

  • argTypes – 関数の引数の型の配列(引数がない場合は、省略できます)。型はreturnTypeと同様ですが、配列の長さを知る方法がないため、arrayはサポートされていません。

  • opts – オプションのオプションオブジェクト。 ccall()を参照してください。

戻り値

C関数を実行するために使用できるJavaScript関数。

メモリへのアクセス

setValue(ptr, value, type[, noSafe])

実行時に特定のメモリアドレスに値を設定します。

  • setValue()getValue()は、アラインされた書き込みと読み取りのみを実行します。

  • typeはLLVM IR型(i8i16i32i64floatdouble、またはi8**のようなポインター型)であり、ccall()またはcwrap()で使用されるJavaScript型ではありません。これは低レベルの操作であり、どの特定の型が使用されているかを気にする必要があります。

引数
  • ptr – メモリアドレスを表すポインタ(数値)。

  • value – 格納する値

  • type – 文字列としてのLLVM IR型(上記の「注」を参照)。

  • noSafe (bool) – 開発者はこの変数を無視する必要があります。これは、SAFE_HEAPコンパイルモードでのみ使用され、一部の専門的なユースケースで無限再帰を回避するのに役立ちます。

getValue(ptr, type[, noSafe])

実行時に特定のメモリアドレスで値を取得します。

  • setValue()getValue()は、アラインされた書き込みと読み取りのみを実行します!

  • typeはLLVM IR型(i8i16i32i64floatdouble、またはi8**のようなポインター型)であり、ccall()またはcwrap()で使用されるJavaScript型ではありません。これは低レベルの操作であり、どの特定の型が使用されているかを気にする必要があります。

引数
  • ptr – メモリアドレスを表すポインタ(数値)。

  • type – 文字列としてのLLVM IR型(上記の「注」を参照)。

  • noSafe (bool) – 開発者はこの変数を無視する必要があります。これは、SAFE_HEAPコンパイルモードでのみ使用され、一部の専門的なユースケースで無限再帰を回避するのに役立ちます。

戻り値

指定されたメモリアドレスに格納されている値。

変換関数 — 文字列、ポインタ、配列

UTF8ToString(ptr[, maxBytesToRead])

Emscripten HEAP内のヌル終端UTF8エンコードされた文字列へのポインタptrが与えられた場合、その文字列のコピーをJavaScriptのStringオブジェクトとして返します。

引数
  • ptr – Emscripten HEAP内のヌル終端UTF8エンコードされた文字列へのポインタ。

  • maxBytesToRead – 読み取る最大バイト数を指定するオプションの長さ。最初の0バイトまで文字列をスキャンするには、このパラメータを省略できます。maxBytesToReadが渡され、[ptr, ptr+maxBytesToReadr)の文字列に途中でヌルバイトが含まれている場合、文字列はそのバイトインデックスで切り詰められます(つまり、maxBytesToReadは正確な長さ[ptr, ptr+maxBytesToRead)の文字列を生成しません)。注意:UTF8ToString()をmaxBytesToReadあり/なしで頻繁に使用すると、JS JIT最適化が妨げられる可能性があるため、一方のスタイルを一貫して使用することを検討する価値があります。

戻り値

JavaScriptのStringオブジェクト

stringToUTF8(str, outPtr, maxBytesToWrite)

指定されたJavaScriptのStringオブジェクトstrを、アドレスoutPtrのEmscripten HEAPにコピーします。これは、ヌル終端され、UTF8形式でエンコードされます。

コピーには、HEAP内に最大でstr.length*4+1バイトのスペースが必要です。文字列をエンコードするために必要な正確なバイト数(ヌル終端文字を除く)を計算するには、関数lengthBytesUTF8()を使用できます。

引数
  • str (String) – JavaScriptのStringオブジェクト。

  • outPtrstrからコピーされたデータへのポインタ。UTF8形式でエンコードされ、ヌル終端されます。

  • maxBytesToWrite – この関数が書き出すことができる最大バイト数の制限。文字列がこれより長い場合、出力は切り捨てられます。出力された文字列は、maxBytesToWrite > 0である限り、切り捨てが発生した場合でも、常にヌル終端されます。

UTF16ToString(ptr)

Emscripten HEAP内のヌル終端UTF16LEエンコードされた文字列へのポインタptrが与えられた場合、その文字列のコピーをJavaScriptのStringオブジェクトとして返します。

引数
  • ptr – Emscripten HEAP内のヌル終端UTF16LEエンコードされた文字列へのポインタ。

戻り値

JavaScriptのStringオブジェクト

stringToUTF16(str, outPtr, maxBytesToWrite)

指定されたJavaScriptのStringオブジェクトstrを、アドレスoutPtrのEmscripten HEAPにコピーします。これは、ヌル終端され、UTF16LE形式でエンコードされます。

コピーには、HEAP内に正確に(str.length+1)*2バイトの領域が必要です。

引数
  • str (String) – JavaScriptのStringオブジェクト。

  • outPtrstrからコピーされたデータへのポインタ。UTF16LE形式でエンコードされ、null終端されています。

  • maxBytesToWrite – この関数が書き込める最大バイト数の制限。文字列がこれより長い場合、出力は切り捨てられます。出力された文字列は、たとえ切り捨てが発生した場合でも、null終端されます。ただし、null終端文字のためのスペースを確保するために、maxBytesToWrite >= 2である必要があります。

UTF32ToString(ptr)

Emscripten HEAP内のnull終端されたUTF32LEエンコードされた文字列へのポインタptrが与えられた場合、その文字列のコピーをJavaScriptのStringオブジェクトとして返します。

引数
  • ptr – Emscripten HEAP内のnull終端されたUTF32LEエンコードされた文字列へのポインタ。

戻り値

JavaScriptのStringオブジェクト。

stringToUTF32(str, outPtr, maxBytesToWrite)

指定されたJavaScriptのStringオブジェクトstrを、Emscripten HEAP内のアドレスoutPtrにコピーします。null終端され、UTF32LE形式でエンコードされます。

コピーには、HEAP内に最大で(str.length+1)*4バイトの領域が必要になりますが、str.lengthは文字列内の文字数ではなく、文字列内のUTF-16コードユニットの数を返すため、より少ないスペースで済む場合があります。文字列をエンコードするために必要な正確なバイト数(null終端文字を除く)を計算するには、関数lengthBytesUTF32()を使用できます。

引数
  • str (String) – JavaScriptのStringオブジェクト。

  • outPtrstrからコピーされたデータへのポインタ。UTF32LE形式でエンコードされ、null終端されています。

  • maxBytesToWrite – この関数が書き込める最大バイト数の制限。文字列がこれより長い場合、出力は切り捨てられます。出力された文字列は、たとえ切り捨てが発生した場合でも、null終端されます。ただし、null終端文字のためのスペースを確保するために、maxBytesToWrite >= 4である必要があります。

AsciiToString(ptr)

ASCIIまたはLatin-1エンコードされた文字列をJavaScriptのStringオブジェクトに変換します。

引数
  • ptrStringに変換されるポインタ。

戻り値

ptrからのデータを含むJavaScriptのString

戻り値の型

String

intArrayFromString(stringy, dontAddNull[, length])

これは、JavaScriptの文字列を、0で終端されたCスタイルの数値配列に変換します。

引数
  • stringy (String) – 変換する文字列。

  • dontAddNull (bool) – trueの場合、新しい配列はゼロ終端されません。

  • length – 配列の長さ(オプション)。

戻り値

stringyから作成された配列。

intArrayToString(array)

これは、ゼロ終端されたCスタイルの数値配列からJavaScriptの文字列を作成します。

引数
  • array – 変換する配列。

戻り値

arrayの内容を含むString

writeArrayToMemory(array, buffer)

配列をヒープ内の指定されたアドレスに書き込みます。配列を書き込む前に、メモリを割り当てる必要があることに注意してください。

引数
  • array – メモリに書き込む配列。

  • buffer (Number) – arrayが書き込まれるアドレス(数値)。

実行時依存関係

通常、実行時依存関係はファイルパケージャやシステムの他の部分によって管理されることに注意してください。開発者がこのAPIを直接使用することはまれです。

addRunDependency(id)

実行時依存関係のリストにidを追加します。

これにより、実行時依存関係が追加され、実行時依存関係カウンタが増加します。

引数
  • id (String) – 操作を表す任意のID。

removeRunDependency(id)

実行時依存関係のリストから指定されたidを削除します。

引数
  • id (String) – 削除する特定の依存関係の識別子(addRunDependency()で追加)。

スタックトレース

stackTrace()

現在のスタックトレースを返します。

スタックトレースは、少なくともIE10およびSafari 6では利用できません。

戻り値

利用可能な場合は、現在のスタックトレース。

メモリモデルの型アクセサ

Emscriptenのメモリ表現では、型付き配列バッファ(ArrayBuffer)を使用してメモリを表し、さまざまなビューから異なる型にアクセスできるようにします。異なる型のメモリにアクセスするためのビューを以下に示します。

HEAP8

8ビット符号付きメモリのビュー。

HEAP16

16ビット符号付きメモリのビュー。

HEAP32

32ビット符号付きメモリのビュー。

HEAPU8

8ビット符号なしメモリのビュー。

HEAPU16

16ビット符号なしメモリのビュー。

HEAPU32

32ビット符号なしメモリのビュー。

HEAPF32

32ビット浮動小数点メモリのビュー。

HEAPF64

64ビット浮動小数点メモリのビュー。