Оберните функцию c ++ с параметром вывода для использования в javascript / node

Решение по использованию списка осей abevieiramota работает очень хорошо, пока вы не используете только один ряд изображений, как указано в комментариях. Использование разумного соотношения сторон для figsize помогает, но все еще далек от совершенства. Например:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9.75, 3))
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.colorbar(im, ax=axes.ravel().tolist())

plt.show()

Функция colorbar предоставляет параметр shrink, который является коэффициентом масштабирования для размер осей цветной панели. Это требует некоторых ручных проб и ошибок. Например:

fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.75)

1
задан user845279 13 July 2018 в 19:30
поделиться

1 ответ

Самый простой способ сопоставить семантику C ++, которую вы показали на JavaScript, - заставить SWIG заставить функцию вести себя так, как если бы вы написали ее в реальном JavaScript вместо C ++. То есть мы собираемся заставить вашу функцию вести себя как следующий псевдословный псевдоним JavaScript:

function test(input) {
    if (error) {
        throw ....
    }
    return input;
}

Чтобы сделать это с помощью SWIG, нам нужно написать несколько typemaps. (В некоторых случаях эти типы уже существуют для нас как часть стандартной библиотеки SWIG, но для char ** нет такой типовой карты, потому что семантика немного менее очевидна).

Я сделал ваш код работать со следующим интерфейсом SWIG, аннотированным ниже:

%module test

// #1
%typemap(in,numinputs=0) char **output (char *tmp) {
    $1 = &tmp; // #2
}

// #3
%typemap(argout,fragment="SWIG_FromCharPtr") char **output {
    $result = SWIG_FromCharPtr(tmp$argnum);
    // Without more effort the following would be an illegal cast I think:
    //SWIG_AppendOutput($result, tmp$argnum);
}

// #4
%typemap(out) int test %{
    if ($1) {
        SWIG_exception_fail(SWIG_ERROR, "Well, that was unexpected");
    }
%}

%inline %{
int test(char *input, char **output) {
    *output = input;
    return 0;
}
%}

По существу, мы сделали здесь 4 вещи:

  1. Карта, которая устанавливает **output, без ввода кода JavaScript. numinputs=0 - это то, что подавляет необходимость получения аргумента из запросов JavaScript.
  2. Вместо этого мы используем локальную переменную, которая будет выводиться исключительно внутри оболочки
  3. После того, как функция была вызвана, используйте значение в нашей локальной переменной, так как функция вернется к JavaScript. Нам нужно ссылаться на него как на tmp$argnum, потому что SWIG внутренне пронумеровал локальную переменную, чтобы избежать столкновений, если карта-схема сопоставляется несколько раз в картотеке типов, но она не делает этого автоматически при обсуждении. Есть несколько стандартных макросов, которые SWIG поставляет для добавления вещей, чтобы возвращать несколько элементов, но здесь они не работают, потому что они заканчивают выполнение незаконного приведения, и мне все равно не нравится использовать эти семантики. Фрагмент здесь гарантирует, что у нас есть некоторая предварительно написанная поддержка строковых выходов, доступных в нашем сгенерированном коде.
  4. Сделайте что-то с исходным возвращаемым значением, в этом случае выведите исключение, если мы получим ненулевое значение (т.е. ошибка) из C ++. Существуют и другие способы решения этой проблемы, но это самый простой способ не просто игнорировать ошибки.

Я почти никогда не использовал поддержку JavaScript SWIG раньше, поэтому, как только я работал мой путь через основную документацию для создания модуля для меня было достаточным для запуска следующего теста:

var test = require("./build/Release/test");

console.log(test.test("blah blah"));

Работала так, как ожидалось. Я также сделал быстрый тест, изменив возвращаемое значение, чтобы заставить исключение, и которое вел себя так же, как и предполагалось.

Отказ от ответственности: это почти удвоило мое воздействие на узел / V8, поэтому тщательно проверяйте мои работы

1
ответ дан Flexo 17 August 2018 в 12:19
поделиться
  • 1
    Похоже, что это лучший вариант. Другой вариант, о котором я думал, - передать объект, который будет содержать возвращенную строку. Подобно stackoverflow.com/a/49137164/845279 – user845279 26 July 2018 в 18:25
Другие вопросы по тегам:

Похожие вопросы: