emscripten-core/emscripten

[Feature request] [Discussion] Document/legalize Embind support for custom marshalling

Open

#9.022 geöffnet am 18. Juli 2019

Auf GitHub ansehen
 (8 Kommentare) (4 Reaktionen) (0 zugewiesene Personen)C++ (3.519 Forks)batch import
embindhelp wanted

Repository-Metriken

Stars
 (27.361 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 19T 10h) (147 gemergte PRs in 30 T)

Beschreibung

I have a C++ class which I want to (un)marshall to JS in a custom way. There is an "unofficial" way of doing so which works at the moment: provide specializations for emscripten::internal::{BindingType,TypeId} in each translation unit where you want them (together with emscripten/bind.h), like this:

namespace emscripten::internal {
	struct BindingType<SomeWeirdType> {
		typedef internal::EM_VAL WireType;
		static WireType toWireType(const SomeWeirdType& foo) {
			// One can also call JS-side functions here and let them construct the new object instead of crafting it here.
			return BindingType<val>::toWireType(val(foo.a * 10 + foo.b));
		}
	};

	struct TypeID<SomeWeirdType> {
		static constexpr TYPEID get() {
			return LightTypeID<val>::get();
		}
	};

	struct TypeID<const SomeWeirdType> {
		static constexpr TYPEID get() {
			return LightTypeID<val>::get();
		}
	};

	struct TypeID<SomeWeirdType&> {
		static constexpr TYPEID get() {
			return LightTypeID<val>::get();
		}
	};

	struct TypeID<const SomeWeirdType&> {
		static constexpr TYPEID get() {
			return LightTypeID<val>::get();
		}
	};
}

However, this is not documented anywhere. Is it likely for this API to change rapidly? If not, it would be nice to have some documentation and, possibly, legalization of such activities (at the very least, moving it out of internal namespace).

How about establishing a documented custom marshalling API?

Some example usecases are:

  1. std::function which I want to convert to JS function (forgetting about ownership and leaks) to provide callbacks to JS easily.
  2. Wrapper class around HTMLElementDocument or some other JS api which I want to call from C++ for whatever reason instead of writing JS glue code. Say, it holds a reference to emscripten::val and just redirects calls to val::operator(). Something like Rust's wasm-bindgen's web_sys.
  3. Custom Promise-like class which I want to interop with JS, so I cannot just directly bind properties/methods, hence I have to create a new object on JS side in a specific way (probably like in Rust's wasm_bindgen_futures, but I haven't looked into it).

Contributor Guide