The Embind C++ class emscripten::val
(defined in val.h) is used to transliterate JavaScript code to C++.
Guide material for this class can be found in Using val to transliterate JavaScript to C++.
This class is a C++ data type that can be used to represent (and provide convenient access to) any JavaScript object. You can use it to call a JavaScript object, read and write its properties, or coerce it to a C++ value like a bool
, int
, or std::string
.
For example, the code below shows some simple JavaScript for making an XHR request on a URL:
var xhr = new XMLHttpRequest;
xhr.open("GET", "http://url");
This same code can be written in C++, using global()
to get the symbol for the global XMLHttpRequest
object and then using it to open a URL.
val xhr = val::global("XMLHttpRequest").new_();
xhr.call<void>("open", std::string("GET"), std::string("http://url"));
You can test whether the open
method call was successful using operator[]()
to read an object property, then as()
to coerce the type:
const char* state;
switch (xhr["readyState"].as<int>()) {
case 0:
state = "UNSENT"; break;
case 1:
state = "OPENED"; break;
default:
state = "etc";
}
See Using val to transliterate JavaScript to C++ for other examples.
警告
JavaScript values can’t be shared across threads, so neither can val
instances that bind them.
For example, if you want to cache some JavaScript global as a val
, you need to retrieve and bind separate instances of that global by its name in each thread.
The easiest way to do this is with a thread_local
declaration:
thread_local const val Uint8Array = val::global("Uint8Array");
Returns a raw handle representing this val
. This can be used for
passing raw value handles to JavaScript and retrieving the values on the
other side via Emval.toValue
function. Example:
EM_JS(void, log_value, (EM_VAL val_handle), {
var value = Emval.toValue(val_handle);
console.log(value); // 42
});
val foo(42);
log_value(foo.as_handle());
Creates a val
from a raw handle. This can be used for retrieving values
from JavaScript, where the JavaScript side should wrap a value with
Emval.toHandle
, pass it to C++, and then C++ can use take_ownership
to convert it to a val
instance. Example:
EM_ASYNC_JS(EM_VAL, fetch_json_from_url, (const char *url), {
var url = UTF8ToString(url);
var response = await fetch(url);
var json = await response.json();
return Emval.toHandle(json);
});
val obj = val::take_ownership(fetch_json_from_url("https://httpbin.org/json"));
std::string author = obj["slideshow"]["author"].as<std::string>();
Looks up a value by the provided name
on the Emscripten Module object.
Constructor.
Creates a val
by conversion from any Embind-compatible C++ type.
For example, val(true)
or val(std::string("foo"))
.
Constructs a val
instance from a string literal.
Removes the currently bound value by decreasing its refcount.
Removes a reference to the currently bound value and takes over the provided one.
Removes a reference to the currently bound value and creates another reference to
the value behind the provided val
instance.
Checks if the JavaScript object has own (non-inherited) property with the specified name.
Assumes that current value is a constructor, and creates an instance of it. Equivalent to a JavaScript expression new currentValue(…).
Set the specified (key
) property of a JavaScript object (accessed through a val
) with the value v
.
Assumes that current value is a function, and invokes it with provided arguments.
Invokes the specified method (name
) on the current object with provided arguments.
Converts current value to the specified C++ type.
Returns the result of a JavaScript typeof
operator invoked on the current value.
Copies a JavaScript array into a std::vector<T>
, converting each element via .as<T>()
.
For a more efficient but unsafe version working with numbers, see convertJSArrayToNumberVector
.
val v – The JavaScript array to be copied
A std::vector<T>
made from the javascript array
Converts a JavaScript array into a std::vector<T>
efficiently, as if using the javascript Number() function on each element.
This is way more efficient than vecFromJSArray
on any array with more than 2 values, but is not suitable for arrays of non-numeric values.
No type checking is done, so any invalid array entry will silently be replaced by a NaN value (or 0 for integer types).
val v – The JavaScript (typed) array to be copied
A std::vector<T> made from the javascript array
Pauses the C++ to await
the Promise
/ thenable.
The fulfilled value.
备注
This method requires ASYNCIFY to be enabled.
The co_await
operator allows awaiting JavaScript promises represented by val
.
It’s compatible with any C++20 coroutines, but should be normally used inside
a val
-returning coroutine which will also become a Promise
.
For example, it allows you to implement the equivalent of this JavaScript async
/await
function:
async function foo() { const response = await fetch("http://url"); const json = await response.json(); return json; } export { foo };as a C++ coroutine:
val foo() { val response = co_await val::global("fetch")(std::string("http://url")); val json = co_await response.call<val>("json"); return json; } EMSCRIPTEN_BINDINGS(module) { function("foo", &foo); }
Unlike the await()
method, it doesn’t need Asyncify as it uses native C++ coroutine transform.
A val
representing the fulfilled value of this promise.