如何使用 Emscripten 将对象从 Javascript 传递到 C++

Posted

技术标签:

【中文标题】如何使用 Emscripten 将对象从 Javascript 传递到 C++【英文标题】:How do I pass objects from Javascript to C++ using Emscripten 【发布时间】:2014-07-02 07:22:13 【问题描述】:

我想将 javascript 对象从 JS 传递回 C++ 类/方法。 我有以下简单的代码 sn-p 不起作用:

// 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

错误是在“emscripten/val.h”中包含的“wire.h”中引起的。

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

【问题讨论】:

另一种传递对象的方式:leaningtech.com/cheerp 它使用的是 C++11 特性,所以正确的命令应该是em++ -std=c++11 Access_Objects.cpp 【参考方案1】:

还有其他方式可以在 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 更烦人(如果它工作正常),但它最终也应该更有效。一旦你打包了你需要的主要库,你会发现它非常稳定。然而,在大多数情况下,使用诸如 abs() 之类的 C++ 版本的函数很容易。

您可以在此处了解有关创建自己的库的更多信息:http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-call-javascript-from-native

【讨论】:

【参考方案2】:

如上所述,您需要将 -std=c++11 传递给编译器,因为它使用 c++11

【讨论】:

以上是关于如何使用 Emscripten 将对象从 Javascript 传递到 C++的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Emscripten 将 Hello Word 从 Swift 编译为 JavaScript

如何将 emscripten 浏览器输入法从 window.prompt 更改为更明智的方法?

如何在 React / React Native 中使用 Emscripten 编译的 JavaScript

是否可以使用 emscripten 使用 Javascript 从 C++ 打印字符串?

使用 emscripten 将字符串从 C++ 传递给 JS

如何使用 es6 导入加载 emscripten 生成的模块?