Die JavaScript-APIs in preamble.js bieten programmatischen Zugriff für die Interaktion mit dem kompilierten C-Code, einschließlich: Aufrufen von kompilierten C-Funktionen, Zugriff auf Speicher, Konvertieren von Zeigern in JavaScript-Strings und Strings in Zeiger (mit verschiedenen Kodierungen/Formaten) und andere Komfortfunktionen.
Wir nennen dies „preamble.js“, weil Emscriptens Ausgabe-JS auf hoher Ebene die Präambel (aus src/preamble.js), dann den kompilierten Code und dann das Postamble enthält. (Etwas detaillierter enthält die Präambel Dienstprogramme und Setup, während das Postamble die Dinge verbindet und die Ausführung der Anwendung handhabt.)
Der Präambel-Code ist im Ausgabe-JS enthalten, das dann zusammen mit allen von Ihnen hinzugefügten --pre-js- und --post-js-Dateien und Code aus beliebigen JavaScript-Bibliotheken (--js-library) vom Compiler optimiert wird. Das bedeutet, dass Sie Methoden aus der Präambel direkt aufrufen können, und der Compiler wird erkennen, dass Sie sie benötigen, und sie nicht als unbenutzt entfernen.
Wenn Sie Präambel-Methoden von einem Ort aufrufen möchten, den der Compiler nicht sehen kann, wie z.B. ein anderes Skript-Tag im HTML, müssen Sie sie exportieren. Dazu fügen Sie sie zu EXPORTED_RUNTIME_METHODS hinzu (zum Beispiel exportiert -sEXPORTED_RUNTIME_METHODS=ccall,cwrap die Funktionen ccall und cwrap). Nach dem Export können Sie auf sie über das Module-Objekt zugreifen (z.B. als Module.ccall).
Hinweis
Wenn Sie versuchen, Module.ccall oder eine andere Laufzeitmethode ohne Export zu verwenden, erhalten Sie einen Fehler. Bei einem Build mit -sASSERTIONS gibt der Compiler Code aus, der eine nützliche Fehlermeldung anzeigt, die erklärt, dass Sie sie exportieren müssen. Im Allgemeinen ist es nützlich, mit Assertions zu bauen, wenn Sie etwas Ungewöhnliches sehen.
Inhaltsverzeichnis
ccall(ident, returnType, argTypes, args, opts)¶Ruft eine kompilierte C-Funktion aus JavaScript auf.
Die Funktion führt eine kompilierte C-Funktion aus JavaScript aus und gibt das Ergebnis zurück. C++-Name-Mangling bedeutet, dass „normale“ C++-Funktionen nicht aufgerufen werden können; die Funktion muss entweder in einer .c-Datei definiert sein oder eine C++-Funktion sein, die mit extern "C" definiert ist.
returnType und argTypes ermöglichen es Ihnen, die Typen der Parameter und des Rückgabewerts anzugeben. Die möglichen Typen sind "number", "string", "array" oder "boolean", die den entsprechenden JavaScript-Typen entsprechen. Verwenden Sie "number" für jeden numerischen Typ oder C-Zeiger, string für C char*, die Strings darstellen, "boolean" für einen booleschen Typ, "array" für JavaScript-Arrays und Typed Arrays, die 8-Bit-Integer-Daten enthalten - das heißt, die Daten werden in ein C-Array von 8-Bit-Integern geschrieben; und insbesondere wenn Sie hier ein Typed Array bereitstellen, muss es ein Uint8Array oder Int8Array sein. Wenn Sie ein Array eines anderen Datentyps erhalten möchten, können Sie manuell Speicher zuweisen und hineinschreiben, und dann hier einen Zeiger bereitstellen (als "number", da Zeiger nur Zahlen sind).
// 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
Hinweis
ccall verwendet den C-Stack für temporäre Werte. Wenn Sie einen String übergeben, ist dieser nur „lebendig“, bis der Aufruf abgeschlossen ist. Wenn der aufgerufene Code den Zeiger zur späteren Verwendung speichert, kann er auf ungültige Daten zeigen.
Wenn Sie möchten, dass ein String dauerhaft lebt, können Sie ihn z.B. mit _malloc und stringToUTF8() erstellen. Sie müssen ihn jedoch später manuell löschen!
LLVM-Optimierungen können Funktionen inlinen und entfernen, wonach Sie sie nicht mehr aufrufen können. Ähnlich sind Funktionsnamen, die vom Closure Compiler minimiert wurden, unzugänglich. In beiden Fällen besteht die Lösung darin, die Funktionen der Liste EXPORTED_FUNCTIONS hinzuzufügen, wenn Sie emcc aufrufen.
-sEXPORTED_FUNCTIONS=_main,_myfunc"
(Beachten Sie, dass wir auch main exportieren - wenn wir das nicht täten, würde der Compiler annehmen, dass wir es nicht brauchen.) Exportierte Funktionen können dann wie gewohnt aufgerufen werden.
a_result = Module.ccall('myfunc', 'number', ['number'], [10])
ident – Der Name der aufzurufenden C-Funktion.
returnType – Der Rückgabetyp der Funktion. Beachten Sie, dass array nicht unterstützt wird, da wir die Länge des Arrays nicht kennen können. Für eine void-Funktion kann dies null sein (Hinweis: der JavaScript-Wert null, nicht ein String, der das Wort „null“ enthält).
Hinweis
64-Bit-Ganzzahlen werden zu zwei 32-Bit-Parametern, für die niedrigen und hohen Bits (da 64-Bit-Ganzzahlen in JavaScript-Zahlen nicht dargestellt werden können).
argTypes – Ein Array der Argumenttypen für die Funktion (wenn keine Argumente vorhanden sind, kann dies weggelassen werden).
args – Ein Array der Argumente für die Funktion als native JavaScript-Werte (wie in returnType). Beachten Sie, dass String-Argumente auf dem Stack gespeichert werden (der JavaScript-String wird zu einem C-String auf dem Stack).
Das Ergebnis des Funktionsaufrufs als nativer JavaScript-Wert (wie in returnType) oder, wenn die Option async gesetzt ist, ein JavaScript-Promise des Ergebnisses.
Ein optionales Options-Objekt. Es kann die folgenden Eigenschaften enthalten:
async: Wenn true, impliziert dies, dass der ccall eine asynchrone Operation durchführt. Dies setzt voraus, dass Sie mit Asyncify-Unterstützung bauen.
Hinweis
Asynchrone Aufrufe unterstützen derzeit keine Promise-Fehlerbehandlung.
cwrap(ident, returnType, argTypes)¶Gibt einen nativen JavaScript-Wrapper für eine C-Funktion zurück.
Dies ähnelt ccall(), gibt aber eine JavaScript-Funktion zurück, die beliebig oft wiederverwendet werden kann. Die C-Funktion kann in einer C-Datei definiert oder eine C-kompatible C++-Funktion sein, die mit extern "C" definiert wurde (um Name-Mangling zu verhindern).
// 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
Hinweis
cwrap verwendet den C-Stack für temporäre Werte. Wenn Sie einen String übergeben, ist dieser nur „lebendig“, bis der Aufruf abgeschlossen ist. Wenn der aufgerufene Code den Zeiger zur späteren Verwendung speichert, kann er auf ungültige Daten zeigen. Wenn Sie möchten, dass ein String dauerhaft lebt, können Sie ihn z.B. mit _malloc und stringToUTF8() erstellen. Sie müssen ihn jedoch später manuell löschen!
Um eine Funktion zu wrappen, muss sie exportiert werden, indem sie der Liste EXPORTED_FUNCTIONS hinzugefügt wird, wenn Sie emcc aufrufen. Wenn eine Funktion nicht exportiert wird, können Optimierungen sie entfernen, und cwrap kann sie zur Laufzeit nicht finden. (In Builds mit aktivierten ASSERTIONS zeigt cwrap in einer solchen Situation einen Fehler an; in Release-Builds ohne Assertions führt der Versuch, eine nicht existierende Funktion zu wrappen, zu einem Fehler, entweder indem undefined zurückgegeben wird oder indem eine Funktion zurückgegeben wird, die beim tatsächlichen Aufruf einen Fehler verursacht, je nachdem, wie cwrap optimiert.)
cwrap ruft nicht tatsächlich kompilierten Code auf (nur das Aufrufen des von ihm zurückgegebenen Wrappers tut dies). Das bedeutet, dass es sicher ist, cwrap frühzeitig aufzurufen, bevor die Laufzeit vollständig initialisiert ist (aber das Aufrufen der zurückgegebenen gewrappten Funktion muss natürlich auf die Laufzeit warten, wie das Aufrufen von kompiliertem Code im Allgemeinen).
-sEXPORTED_FUNCTIONS=_main,_myfunc
Exportierte Funktionen können wie gewohnt aufgerufen werden.
my_func = Module.cwrap('myfunc', 'number', ['number'])
my_func(12)
ident – Der Name der aufzurufenden C-Funktion.
returnType – Der Rückgabetyp der Funktion. Dies kann "number", "string" oder "array" sein, die den entsprechenden JavaScript-Typen entsprechen (verwenden Sie "number" für jeden C-Zeiger und "array" für JavaScript-Arrays und Typed Arrays; beachten Sie, dass Arrays 8-Bit sind), oder für eine void-Funktion kann es null sein (Hinweis: der JavaScript-Wert null, nicht ein String, der das Wort „null“ enthält).
argTypes – Ein Array der Argumenttypen für die Funktion (wenn keine Argumente vorhanden sind, kann dies weggelassen werden). Die Typen sind wie in returnType, außer dass array nicht unterstützt wird, da wir die Länge des Arrays nicht wissen können).
opts – Ein optionales Options-Objekt, siehe ccall().
Eine JavaScript-Funktion, die zur Ausführung der C-Funktion verwendet werden kann.
setValue(ptr, value, type[, noSafe])¶Setzt einen Wert an einer bestimmten Speicheradresse zur Laufzeit.
Hinweis
setValue() und getValue() führen nur ausgerichtete Schreib- und Lesevorgänge durch.
Der type ist ein LLVM IR-Typ (einer von i8, i16, i32, i64, float, double oder ein Zeigertyp wie i8* oder einfach *), nicht JavaScript-Typen, wie sie in ccall() oder cwrap() verwendet werden. Dies ist eine Operation auf niedrigerer Ebene, und wir müssen uns um den spezifischen verwendeten Typ kümmern.
ptr – Ein Zeiger (Zahl), der die Speicheradresse darstellt.
value – Der zu speichernde Wert.
type – Ein LLVM IR-Typ als String (siehe „Hinweis“ oben).
noSafe (bool) – Entwickler sollten diese Variable ignorieren. Sie wird nur im SAFE_HEAP-Kompilierungsmodus verwendet, wo sie in einigen Spezialfällen dazu beitragen kann, unendliche Rekursionen zu vermeiden.
getValue(ptr, type[, noSafe])¶Ruft einen Wert an einer bestimmten Speicheradresse zur Laufzeit ab.
Hinweis
setValue() und getValue() führen nur ausgerichtete Schreib- und Lesevorgänge durch!
Der type ist ein LLVM IR-Typ (einer von i8, i16, i32, i64, float, double oder ein Zeigertyp wie i8* oder einfach *), nicht JavaScript-Typen, wie sie in ccall() oder cwrap() verwendet werden. Dies ist eine Operation auf niedrigerer Ebene, und wir müssen uns um den spezifischen verwendeten Typ kümmern.
ptr – Ein Zeiger (Zahl), der die Speicheradresse darstellt.
type – Ein LLVM IR-Typ als String (siehe „Hinweis“ oben).
noSafe (bool) – Entwickler sollten diese Variable ignorieren. Sie wird nur im SAFE_HEAP-Kompilierungsmodus verwendet, wo sie in einigen Spezialfällen dazu beitragen kann, unendliche Rekursionen zu vermeiden.
Der Wert, der an der angegebenen Speicheradresse gespeichert ist.
UTF8ToString(ptr[, maxBytesToRead])¶Gegeben einen Zeiger ptr auf einen nullterminierten UTF8-kodierten String im Emscripten HEAP, gibt eine Kopie dieses Strings als JavaScript String-Objekt zurück.
ptr – Ein Zeiger auf einen nullterminierten UTF8-kodierten String im Emscripten HEAP.
maxBytesToRead – Eine optionale Länge, die die maximale Anzahl von zu lesenden Bytes angibt. Sie können diesen Parameter weglassen, um den String bis zum ersten 0-Byte zu scannen. Wenn maxBytesToRead übergeben wird und der String bei [ptr, ptr+maxBytesToReadr) ein Null-Byte in der Mitte enthält, wird der String an diesem Byte-Index abgeschnitten (d.h. maxBytesToRead erzeugt keinen String der genauen Länge [ptr, ptr+maxBytesToRead)). N.B. Häufige Verwendung von UTF8ToString() mit und ohne maxBytesToRead kann JS JIT-Optimierungen beeinträchtigen, daher lohnt es sich, eine konsistente Verwendung des einen oder anderen Stils in Betracht zu ziehen.
Ein JavaScript String-Objekt.
stringToUTF8(str, outPtr, maxBytesToWrite)¶Kopiert das gegebene JavaScript String-Objekt str an die Adresse outPtr im Emscripten HEAP, nullterminiert und im UTF8-Format kodiert.
Die Kopie benötigt höchstens str.length*4+1 Bytes Speicherplatz im HEAP. Sie können die Funktion lengthBytesUTF8() verwenden, um die genaue Anzahl der benötigten Bytes (ohne Nullterminator) zur Kodierung des Strings zu berechnen.
str (String) – Ein JavaScript String-Objekt.
outPtr – Zeiger auf Daten, die von str kopiert, im UTF8-Format kodiert und nullterminiert sind.
maxBytesToWrite – Eine Begrenzung für die maximale Anzahl von Bytes, die diese Funktion schreiben kann. Wenn der String länger ist, wird die Ausgabe abgeschnitten. Der ausgegebene String wird immer nullterminiert sein, auch wenn eine Trunkierung aufgetreten ist, solange maxBytesToWrite > 0 ist.
UTF16ToString(ptr)¶Gegeben einen Zeiger ptr auf einen nullterminierten UTF16LE-kodierten String im Emscripten HEAP, gibt eine Kopie dieses Strings als JavaScript String-Objekt zurück.
ptr – Ein Zeiger auf einen nullterminierten UTF16LE-kodierten String im Emscripten HEAP.
Ein JavaScript String-Objekt.
stringToUTF16(str, outPtr, maxBytesToWrite)¶Kopiert das gegebene JavaScript String-Objekt str an die Adresse outPtr im Emscripten HEAP, nullterminiert und im UTF16LE-Format kodiert.
Die Kopie benötigt genau (str.length+1)*2 Bytes Speicherplatz im HEAP.
str (String) – Ein JavaScript String-Objekt.
outPtr – Zeiger auf Daten, die von str kopiert, im UTF16LE-Format kodiert und nullterminiert sind.
maxBytesToWrite – Eine Begrenzung der maximalen Anzahl von Bytes, die diese Funktion schreiben kann. Wenn der String länger ist, wird die Ausgabe abgeschnitten. Der ausgegebene String wird immer nullterminiert sein, auch wenn eine Trunkierung aufgetreten ist, solange maxBytesToWrite >= 2 ist, so dass Platz für den Nullterminator ist.
UTF32ToString(ptr)¶Gegeben einen Zeiger ptr auf einen nullterminierten UTF32LE-kodierten String im Emscripten HEAP, gibt eine Kopie dieses Strings als JavaScript String-Objekt zurück.
ptr – Ein Zeiger auf einen nullterminierten UTF32LE-kodierten String im Emscripten HEAP.
Ein JavaScript String-Objekt.
stringToUTF32(str, outPtr, maxBytesToWrite)¶Kopiert das gegebene JavaScript String-Objekt str an die Adresse outPtr im Emscripten HEAP, nullterminiert und im UTF32LE-Format kodiert.
Die Kopie benötigt höchstens (str.length+1)*4 Bytes Speicherplatz im HEAP, kann aber weniger verbrauchen, da str.length nicht die Anzahl der Zeichen im String zurückgibt, sondern die Anzahl der UTF-16-Code-Einheiten im String. Sie können die Funktion lengthBytesUTF32() verwenden, um die genaue Anzahl der Bytes (ohne Nullterminator) zu berechnen, die zur Kodierung des Strings benötigt werden.
str (String) – Ein JavaScript String-Objekt.
outPtr – Zeiger auf Daten, die von str kopiert, im UTF32LE-Format kodiert und nullterminiert sind.
maxBytesToWrite – Eine Begrenzung der maximalen Anzahl von Bytes, die diese Funktion schreiben kann. Wenn der String länger ist, wird die Ausgabe abgeschnitten. Der ausgegebene String wird immer nullterminiert sein, auch wenn eine Trunkierung aufgetreten ist, solange maxBytesToWrite >= 4 ist, so dass Platz für den Nullterminator ist.
AsciiToString(ptr)¶Konvertiert einen ASCII- oder Latin-1-kodierten String in ein JavaScript String-Objekt.
ptr – Der Zeiger, der in einen String konvertiert werden soll.
Ein JavaScript String, der die Daten von ptr enthält.
String
intArrayFromString(stringy, dontAddNull[, length])¶Dies konvertiert einen JavaScript-String in ein C-ähnliches Array von Zahlen, 0-terminiert.
stringy (String) – Der zu konvertierende String.
dontAddNull (bool) – Wenn true, ist das neue Array nicht null-terminiert.
length – Die Länge des Arrays (optional).
Das aus stringy erstellte Array.
intArrayToString(array)¶Dies erstellt einen JavaScript-String aus einem null-terminierten C-ähnlichen Array von Zahlen.
array – Das zu konvertierende Array.
Ein String, der den Inhalt von array enthält.
writeArrayToMemory(array, buffer)¶Schreibt ein Array an eine angegebene Adresse im Heap. Beachten Sie, dass Speicher für das Array reserviert werden muss, bevor es geschrieben wird.
array – Das Array, das in den Speicher geschrieben werden soll.
buffer (Number) – Die Adresse (Zahl), an die array geschrieben werden soll.
Beachten Sie, dass Laufzeitabhängigkeiten im Allgemeinen vom Dateipackager und anderen Teilen des Systems verwaltet werden. Es ist selten, dass Entwickler diese API direkt verwenden.
addRunDependency(id)¶Fügt eine id zur Liste der Laufzeitabhängigkeiten hinzu.
Dies fügt eine Laufzeitabhängigkeit hinzu und erhöht den Zähler der Laufzeitabhängigkeiten.
id (String) – Eine beliebige ID, die den Vorgang darstellt.
removeRunDependency(id)¶Entfernt eine angegebene id aus der Liste der Laufzeitabhängigkeiten.
id (String) – Der Bezeichner für die spezifische Abhängigkeit, die entfernt werden soll (hinzugefügt mit addRunDependency())
stackTrace()¶Gibt den aktuellen Stack-Trace zurück.
Hinweis
Der Stack-Trace ist zumindest unter IE10 und Safari 6 nicht verfügbar.
Der aktuelle Stack-Trace, falls verfügbar.
Die Emscripten-Speicherrepräsentation verwendet einen typisierten Array-Puffer (ArrayBuffer), um den Speicher darzustellen, wobei verschiedene Ansichten darauf Zugriff auf die verschiedenen Typen ermöglichen. Die Ansichten für den Zugriff auf verschiedene Speichertypen sind unten aufgeführt.
HEAP8¶Ansicht für 8-Bit vorzeichenbehafteten Speicher.
HEAP16¶Ansicht für 16-Bit vorzeichenbehafteten Speicher.
HEAP32¶Ansicht für 32-Bit vorzeichenbehafteten Speicher.
HEAPU8¶Ansicht für 8-Bit vorzeichenlosen Speicher.
HEAPU16¶Ansicht für 16-Bit vorzeichenlosen Speicher.
HEAPU32¶Ansicht für 32-Bit vorzeichenlosen Speicher.
HEAPF32¶Ansicht für 32-Bit Float-Speicher.
HEAPF64¶Ansicht für 64-Bit Float-Speicher.