如何使用Emscripten将JavaScript对象传递给C++?

10
我想从JS传回一个Javascript对象到C++类/方法。我有以下简单的代码片段,但它无法工作:
// Access JS objects in C++ like C++ objects

#include "emscripten/val.h"   //Causing errors !

using namespace emscripten;
int main() {
    val Math = val::global("Math");
    return Math.call("abs", -10); // returns 10
}

我使用以下命令在Windows上使用Emscripten进行编译:

cmd> emcc Access_Objects.cpp

我收到了大量错误日志:

In file included from Access_Objects.cpp:2:
In file included from C:\Program Files\Emscripten\emscripten\1.16.0\system\inclu
de\emscripten/val.h:4:
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:2
4:5: error:
      unknown type name 'constexpr'
    constexpr bool has_unbound_type_names = true;
    ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:2
4:15: error:
      expected unqualified-id
    constexpr bool has_unbound_type_names = true;
              ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:5
6:21: error:
      use of undeclared identifier 'has_unbound_type_names'
                if (has_unbound_type_names || std::is_polymorphic<C>::value) {
                    ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:6
7:17: error:
      use of undeclared identifier 'has_unbound_type_names'
            if (has_unbound_type_names || std::is_polymorphic<C>::value) {
                ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:8
2:40: error:
      a space is required between consecutive right angle brackets (use '> >')
        struct TypeID<std::unique_ptr<T>> {
                                       ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:9
8:42: error:
      a space is required between consecutive right angle brackets (use '> >')
        struct TypeID<AllowedRawPointer<T>> {
                                         ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
82:9: error:
      unknown type name 'constexpr'
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(char);
        ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:13: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
82:9: error:
      expected member name or ';' after declaration specifiers
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(char);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:23: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ~~~~~~~~~ ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
83:9: error:
      unknown type name 'constexpr'
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(signed char);
        ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:13: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
83:9: error:
      expected member name or ';' after declaration specifiers
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(signed char);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:23: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ~~~~~~~~~ ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
84:9: error:
      unknown type name 'constexpr'
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(unsigned char);
        ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:13: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
84:9: error:
      expected member name or ';' after declaration specifiers
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(unsigned char);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:23: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ~~~~~~~~~ ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
85:9: error:
      unknown type name 'constexpr'
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(signed short);
        ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:13: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
85:9: error:
      expected member name or ';' after declaration specifiers
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(signed short);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:23: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ~~~~~~~~~ ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
86:9: error:
      unknown type name 'constexpr'
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(unsigned short);
        ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:13: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
86:9: error:
      expected member name or ';' after declaration specifiers
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(unsigned short);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:23: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ~~~~~~~~~ ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
87:9: error:
      unknown type name 'constexpr'
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(signed int);
        ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:13: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
87:9: error:
      expected member name or ';' after declaration specifiers
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(signed int);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:23: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ~~~~~~~~~ ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
88:9: error:
      unknown type name 'constexpr'
        EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE(unsigned int);
        ^
C:\Program Files\Emscripten\emscripten\1.16.0\system\include\emscripten/wire.h:1
74:13: note:
      expanded from macro 'EMSCRIPTEN_DEFINE_NATIVE_BINDING_TYPE'
            constexpr static WireType toWireType(const type& v) {   \
            ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
ERROR    root: compiler frontend failed to generate LLVM bitcode, halting

错误是在'wire.h'中引起的,该文件被包含在'emscripten/val.h'中。

我应该如何解决这些错误?或者还有其他方法可以将对象从JS传递到C++吗?


传递对象的另一种方式:http://leaningtech.com/cheerp/ - ArtemGr
它使用了C++11的特性,因此正确的命令应该是em++ -std=c++11 Access_Objects.cpp - 小太郎
2个回答

6

JS和C++之间有其他交互的方法。我发现最稳定的方法是通过包装JS函数来构建自己的库,以便从C++中调用它们。

如果你想从C++中调用Javascript的Math.abs()函数,你可以编辑"src/library.JS"文件。在那里,你会发现一个巨大的函数名称映射表,在C++中可用。如果你想要调用你的新函数"JS_Math_abs",你需要添加:

JS_Math_abs: function(value) {
  return Math.abs(value);
},

然后您需要修改C++代码以指定输入和输出类型。添加以下代码:
extern "C" {
  extern int JS_Math_abs(int);
}

不要误解,这种方法比val应该更麻烦(如果它正常工作的话),但最终应该更有效。一旦你包装好了你需要的主要库,你会发现它非常稳定。然而,在大多数情况下,使用C++版本的函数如abs()很容易。
你可以在这里了解更多关于创建自己的库的信息:http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-call-javascript-from-native

0

如上所述,由于使用了c++11,您需要向编译器传递-std=c++11参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接