Как сопоставить ассоциативный массив в JavaScript с картой строк в C ++ с помощью Swig? - PullRequest
0 голосов
/ 07 декабря 2018

Очень похоже на этот вопрос Я хочу обернуть функцию с SWIG, которая принимает map от string с до string с:

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

Для Pythonдостаточно создать псевдоним для карты:

namespace std {
    %template(map_string_string) map<string, string>;
}

Генератор кода создаст функцию-обертку map_string_string и даже автоматически ее использует.

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

Будет правильно вызываться изначения, которые не соответствуют подписи, будут просто пропущены.

Как мне сделать это для JavaScript?

Я попробовал то же самое (конечно), и оболочка get сгенерировалась, но когда япопробуйте вызвать 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

Даже когда я пытаюсь вызвать функцию оболочки 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;
    }
}

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"

Так я создаю модули 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

и, наконец, вот как я их тестирую:

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'})"

В обоих случаях - Python и JavaScript - api.foo() работает, как и ожидалось.api.bar() может быть выполнено на Python, но в JavaScript выдается ошибка, которую я написал.

1 Ответ

0 голосов
/ 10 декабря 2018

Мне кажется, что текущая версия swig (3.0.12) не имеет встроенной поддержки для сопоставления объекта JavaScript или примитива с map.Я думаю, вам придется написать свой собственный преобразователь, который принимает объект JavaScript и преобразует его в C ++ map.См. эту статью , чтобы получить небольшую помощь по этому вопросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...