// Copyright 2019 The Emscripten Authors. All rights reserved. // Emscripten is available under two separate licenses, the MIT license and the // University of Illinois/NCSA Open Source License. Both these licenses can be // found in the LICENSE file. #include #include #include #include #include #include using namespace emscripten; // Class which wraps int and have no explicit or implicit conversions. struct IntWrapper { int get() const { return value; } static IntWrapper create(int v) { return IntWrapper(v); } private: explicit IntWrapper(int v) : value(v) {} int value; }; // Need for SFINAE-based specialization testing. template struct IsIntWrapper : std::false_type {}; template<> struct IsIntWrapper : std::true_type {}; // We will pass IntWrapper between C++ and JavaScript via IntWrapperIntermediate // which should be already registered by embind on both C++ and JavaScript sides. // That way we can write C++ conversions only and use standard JS conversions. using IntWrapperIntermediate = int; // Specify custom (un)marshalling for all types satisfying IsIntWrapper. namespace emscripten { namespace internal { template struct TypeID::value, void>::type> { static constexpr TYPEID get() { return TypeID::get(); } }; template struct BindingType::value, void>::type> { typedef typename BindingType::WireType WireType; constexpr static WireType toWireType(const T& v, rvp::default_tag) { return BindingType::toWireType(v.get(), rvp::default_tag{}); } constexpr static T fromWireType(WireType v) { return T::create(BindingType::fromWireType(v)); } }; } // namespace internal } // namespace emscripten template void test() { IntWrapper x = IntWrapper::create(10); val js_func = val::module_property("js_func"); IntWrapper y = js_func(val(std::forward(x))).as(); printf("C++ got %d\n", y.get()); } int main(int argc, char **argv) { test(); test(); test(); test(); return 0; }