Path: blob/main/test/embind/test_custom_marshal.cpp
4150 views
// Copyright 2019 The Emscripten Authors. All rights reserved.1// Emscripten is available under two separate licenses, the MIT license and the2// University of Illinois/NCSA Open Source License. Both these licenses can be3// found in the LICENSE file.45#include <stdio.h>6#include <emscripten.h>7#include <emscripten/bind.h>8#include <emscripten/val.h>9#include <type_traits>10#include <string>1112using namespace emscripten;1314// Class which wraps int and have no explicit or implicit conversions.15struct IntWrapper {16int get() const {17return value;18}19static IntWrapper create(int v) {20return IntWrapper(v);21}2223private:24explicit IntWrapper(int v) : value(v) {}25int value;26};2728// Need for SFINAE-based specialization testing.29template<typename T> struct IsIntWrapper : std::false_type {};30template<> struct IsIntWrapper<IntWrapper> : std::true_type {};3132// We will pass IntWrapper between C++ and JavaScript via IntWrapperIntermediate33// which should be already registered by embind on both C++ and JavaScript sides.34// That way we can write C++ conversions only and use standard JS conversions.35using IntWrapperIntermediate = int;3637// Specify custom (un)marshalling for all types satisfying IsIntWrapper.38namespace emscripten {39namespace internal {40template<typename T>41struct TypeID<T, typename std::enable_if<IsIntWrapper<T>::value, void>::type> {42static constexpr TYPEID get() {43return TypeID<IntWrapperIntermediate>::get();44}45};4647template<typename T>48struct BindingType<T, typename std::enable_if<IsIntWrapper<T>::value, void>::type> {49typedef typename BindingType<IntWrapperIntermediate>::WireType WireType;5051constexpr static WireType toWireType(const T& v, rvp::default_tag) {52return BindingType<IntWrapperIntermediate>::toWireType(v.get(), rvp::default_tag{});53}54constexpr static T fromWireType(WireType v) {55return T::create(BindingType<IntWrapperIntermediate>::fromWireType(v));56}57};58} // namespace internal59} // namespace emscripten6061template<typename T>62void test() {63IntWrapper x = IntWrapper::create(10);64val js_func = val::module_property("js_func");65IntWrapper y = js_func(val(std::forward<T>(x))).as<IntWrapper>();66printf("C++ got %d\n", y.get());67}6869int main(int argc, char **argv) {70test<IntWrapper>();71test<IntWrapper&>();72test<const IntWrapper>();73test<const IntWrapper&>();74return 0;75}767778