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

时间:2018-12-07 06:36:18

标签: javascript c++ swig stdmap

this question类似,我想用SWIG包装一个函数,该函数将map的{​​{1}}到string s:

string

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

void foo(std::map<std::string, std::string> const& args);

代码生成器将创建包装函数namespace std { %template(map_string_string) map<string, string>; } ,甚至自动使用它。

map_string_string

将被正确调用,不适合签名的值将被忽略。

如何针对JavaScript执行此操作?

我尝试了相同的操作(当然),并且生成了包装器,但是当我尝试这样调用my_module.foo({'a': 'b', 'c', 'd'}) 时:

foo

我明白了

my_module.foo({'a':'b', 'c':'d'});

即使我尝试调用包装器函数/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 ,也遇到此错误。

还有另一种用JavaScript编写“字符串映射”的方法吗?还是有一张简单的收据就可以将关联数组包装在Swig中?

编辑:为了完整起见,我添加了已使用的源文件:

map_string_string

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; } }

api.i

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

%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"

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

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

在两种情况下-Python和JavaScript-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'})" 都按预期执行。 api.foo()可以在Python上执行,但在JavaScript中会抛出我发布的错误。

1 个答案:

答案 0 :(得分:5)

我似乎当前版本的swig(3.0.12)不具有将JavaScript对象或基元映射到map的内置支持。我认为您将必须编写自己的转换器,该转换器需要一个JavaScript对象并将其转换为C ++ map。请参阅this article,以获取一些帮助。