如何使用Swig将JavaScript中的关联数组映射到C++中的字符串映射?

fra*_*ans 11 javascript c++ swig stdmap

颇为相似,这个问题我想包装与痛饮函数,该函数mapstrings到stringS:

void foo(std::map<std::string, std::string> const& args);
Run Code Online (Sandbox Code Playgroud)

对于Python,它足以为地图创建别名:

namespace std {
    %template(map_string_string) map<string, string>;
}
Run Code Online (Sandbox Code Playgroud)

代码生成器将创建包装函数map_string_string,甚至自动使用它.

my_module.foo({'a': 'b', 'c', 'd'})
Run Code Online (Sandbox Code Playgroud)

将被正确调用,不符合签名的值将被忽略.

我如何为JavaScript执行此操作?

我尝试了相同的(当然)和包装器生成但是当我尝试这样调用时foo:

my_module.foo({'a':'b', 'c':'d'});
Run Code Online (Sandbox Code Playgroud)

我明白了

/path/to/example.js:3
my_module.foo({'a':'b', 'c':'d'});
          ^

Error: in method 'foo', argument 1 of type 'std::map< std::string,std::string > const &'
    at Object.<anonymous> (/path/to/example.js:8:7)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3
Run Code Online (Sandbox Code Playgroud)

即使我尝试调用包装函数,map_string_string我也会收到此错误..

还有另一种在JavaScript中编写"字符串映射"的方法吗?或者是否有一个简单的收据来包装Swig中的关联数组?

编辑:为了完整性,我添加了我使用过的源文件:

api.h

#pragma once

#include <string>
#include <map>
#include <iostream>

static void foo(std::string const& value) noexcept {
  std::cout << value << std::endl;
}

static void bar(std::map<std::string, std::string> const& args) noexcept {
    for (auto && e : args) {
        std::cout << e.first << ": " << e.second << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

api.i

%module api 
%include "std_string.i"
%include "std_map.i"
namespace std {
    %template(map_string_string) map<string, string>;
}
%{
    #include <api.h>
%}
%include "api.h"
Run Code Online (Sandbox Code Playgroud)

这是我构建Python和JavaScript模块的方式:

swig -c++ -python -o api_wrap_python.cxx api.i 
g++ -c api_wrap_python.cxx \
    -I/usr/include/python3.6m -I . \
    -fPIC -std=gnu++11
g++ -shared api_wrap_python.o -o _api.so

swig -c++ -javascript -node -o api_wrap_js.cxx api.i
g++ -c api_wrap_js.cxx \
    -I /usr/include/node -I . \
    -std=gnu++11 -fPIC -DBUILDING_NODE_EXTENSION
g++ -shared api_wrap_js.o -o api.node
Run Code Online (Sandbox Code Playgroud)

最后这是我测试它们的方式:

node -e "api = require('api.node'); api.foo('some string'); api.bar({'a':'b'});"
python3 -c "import api; api.foo('hello'); api.bar({'a':'b','c':'d'})"
Run Code Online (Sandbox Code Playgroud)

在这两种情况下 - Python和JavaScript - api.foo()正如预期的那样被激活.api.bar()可以在Python上执行,但在JavaScript中,我发布的错误会被抛出.

Old*_*Pro 5

我看起来像swig(3.0.12)的当前版本没有内置支持将JavaScript对象或基元映射到map.我认为你必须编写自己的转换器,它接受一个JavaScript对象并将其转换为C++ map.请参阅此文章以获得一些帮助.