Внешние функции

При обработке вызова функционального foo в коде MATLAB® генератор кода находит определение foo и генерирует код для его тела. В некоторых случаях вы можете хотеть обойти генерацию кода и вместо этого использовать движок MATLAB, чтобы выполнить вызов. Используйте coder.extrinsic('foo'), чтобы объявить, что вызовы foo не генерируют код и вместо этого используют движок MATLAB для выполнения. В этом контексте foo упоминается как внешняя функция. Эта функциональность доступна только, когда движок MATLAB доступен в MEX-функциях или во время вызовов coder.const во время компиляции.

Если вы генерируете автономный код для функции, которая вызывает foo и включает coder.extrinsic('foo'), генератор кода пытается определить, влияет ли foo на вывод. Если foo не влияет на вывод, доходы генератора кода с генерацией кода, но исключает foo из сгенерированного кода. В противном случае генератор кода производит ошибку компиляции.

Генератор кода автоматически обрабатывает много общих функций визуализации MATLAB, таких как plot, disp и figure, как внешние. Вы не должны явным образом объявлять их как внешние функции при помощи coder.extrinsic. Например, вы можете хотеть вызвать plot, чтобы визуализировать ваши результаты в среде MATLAB. Если вы генерируете MEX-функцию от функции, которая вызывает plot, и затем запустите сгенерированную MEX-функцию, вызовы отправок генератора кода функции plot к движку MATLAB. Если вы генерируете библиотеку или исполняемый файл, сгенерированный код не содержит вызовы функции plot. Отчет генерации кода подсвечивает вызовы от вашего кода MATLAB до внешних функций так, чтобы было легко определить, какие функции поддерживаются только в среде MATLAB.

Для неподдерживаемых функций кроме общих функций визуализации необходимо объявить, что функции являются внешними (см. Разрешение Вызовов функции для Генерации кода). Внешние функции не скомпилированы, но вместо этого выполнены в MATLAB во время симуляции (см. Разрешение Внешних Функций Во время Симуляции).

Существует два способа объявить, что функция является внешней:

Объявление функций MATLAB как внешние функции

Чтобы объявить, что функция MATLAB является внешней, добавьте построение coder.extrinsic во главе основной функции или локальной функции:

coder.extrinsic('function_name_1', ... , 'function_name_n');

Объявление внешних функций

Следующий код объявляет функцию patch MATLAB, внешнюю в локальной функции create_plot. Вы не должны объявлять axis как внешний, потому что axis является одной из общих функций визуализации, которые генератор кода автоматически обрабатывает как внешний.

function c = pythagoras(a,b,color) %#codegen
% Calculates the hypotenuse of a right triangle
%  and displays the triangle. 

c = sqrt(a^2 + b^2);
create_plot(a, b, color);


function create_plot(a, b, color)
%Declare patch as extrinsic

coder.extrinsic('patch'); 

x = [0;a;a];
y = [0;0;b];
patch(x, y, color);
axis('equal');

Генератор кода не производит код для patch и axis, но вместо этого отправляет их MATLAB для выполнения.

Чтобы протестировать функцию, выполните эти шаги:

  1. Преобразуйте pythagoras в MEX-функцию путем выполнения этой команды в посдказке MATLAB:

    codegen -report pythagoras -args {1, 1, [.3 .3 .3]}

  2. Щелкните по ссылке к отчету генерации кода и затем, в отчете, просмотрите код MATLAB для create_plot.

    Отчет подсвечивает patch и функции axis, чтобы указать, что они поддерживаются только в среде MATLAB.

  3. Запустите MEX-функцию путем выполнения этой команды:

    pythagoras_mex(3, 4, [1.0 0.0 0.0]);

    MATLAB отображает график прямоугольного треугольника как красный объект закрашенной фигуры:

Когда Использовать Построение coder.extrinsic

Используйте построение coder.extrinsic для:

Правила для внешних объявлений функции

Наблюдайте следующие правила при объявлении функций, внешних для генерации кода:

  • Объявите функцию, внешнюю, прежде чем вы вызовете ее.

  • Не используйте внешнее объявление в условных операторах.

Осциллограф внешних объявлений функции

Построение coder.extrinsic имеет функциональный осциллограф. Например, рассмотрите следующий код:

function y = foo %#codegen
coder.extrinsic('rat','min');
[N D] = rat(pi);
y = 0;
y = min(N, D);

В этом примере rat и min, столь же обработанном как внешнем каждый раз, они называются в основном функциональном foo. Существует два способа сузить осциллограф внешнего объявления в основной функции:

  • Объявите функцию MATLAB, внешнюю в локальной функции, как в этом примере:

    function y = foo %#codegen
    coder.extrinsic('rat');
    [N D] = rat(pi);
    y = 0;
    y = mymin(N, D);
     
    function y = mymin(a,b)
    coder.extrinsic('min');
    y = min(a,b);
    

    Здесь, функциональный rat является внешним каждый раз, когда он называется в основном функциональном foo, но функциональный min является внешним только, когда названо в локальной функции mymin.

  • Вызовите функцию MATLAB с помощью feval, как описано в Вызове функций MATLAB Используя feval.

Вызов функций MATLAB Используя feval

Функциональный feval автоматически интерпретирован как внешняя функция во время генерации кода. Поэтому можно использовать feval, чтобы удобно вызвать функции, которые вы хотите выполнить в среде MATLAB, а не скомпилированный к сгенерированному коду.

Рассмотрите следующий пример:

function y = foo 
coder.extrinsic('rat');
[N D] = rat(pi);
y = 0;
y = feval('min', N, D);

Поскольку feval является внешним, оператор feval('min', N, D) оценен MATLAB — не скомпилированный — который имеет тот же результат как объявление функционального min, внешнего для только этого вызова. В отличие от этого, функциональный rat является внешним в функциональном foo.

Генератор кода не поддерживает использование feval, чтобы вызвать локальные функции или функции, которые расположены в частной папке.

Внешнее объявление для нестатических методов

Предположим, что вы задаете класс myClass, который имеет нестатический метод foo, и затем создайте экземпляр obj этого класса. Если вы хотите объявить метод obj.foo как внешний в вашем коде MATLAB, который вы предназначаете для генерации кода, следуете этим правилам:

  • Запишите вызов foo как вызов функции. Не пишите вызов при помощи записи через точку.

  • Объявите, что foo является внешним при помощи синтаксиса coder.extrinsic('foo').

Например, задайте myClass как:

classdef myClass
    properties
        prop = 1
    end
    methods
        function y = foo(obj,x)
            y = obj.prop + x;
        end
    end
end

Вот функция MATLAB в качестве примера, которая объявляет foo как внешний.

function y = myFunction(x) %#codegen
coder.extrinsic('foo');
obj = myClass;
y = foo(obj,x);
end

Нестатические методы также известны как обычные методы. См. Методы и Функции (MATLAB).

Разрешение внешних функций во время симуляции

Генератор кода разрешает вызовы внешних функций — функции, которые не поддерживают генерацию кода — можно следующим образом:

Во время симуляции генератор кода производит код для вызова внешней функции, но не генерирует внутренний код для функции. Поэтому можно запустить симуляцию только на платформах, где вы устанавливаете программное обеспечение MATLAB.

Во время генерации кода генератор кода пытается определить, влияет ли внешняя функция на вывод функции, в которой это называется — например, путем возврата mxArrays выходной переменной (см. Работу с mxArrays). При условии, что вывод не изменяется, доходы генерации кода, но внешняя функция исключена из сгенерированного кода. В противном случае генератор кода выпускает ошибку компилятора.

Работа с mxArrays

Выводом внешней функции является mxArray — также вызвал массив MATLAB. Единственные допустимые операции для mxArrays:

  • Хранение mxArrays в переменных

  • Передача mxArrays к функциям и возврату их от функций

  • Преобразование mxArrays к известным типам во время выполнения

Чтобы использовать mxArrays, возвращенный внешними функциями в других операциях, необходимо сначала преобразовать их в известные типы, как описано в Преобразовании mxArrays к Известным Типам.

Преобразование mxArrays к Известным Типам

Чтобы преобразовать mxArray в известный тип, присвойте mxArray переменной, тип которой задан. Во время выполнения mxArray преобразован в тип переменной, присвоенной ему. Однако, если данные в mxArray не сопоставимы с типом переменной, вы получаете ошибку времени выполнения.

Например, рассмотрите этот код:

function y = foo %#codegen
coder.extrinsic('rat');
[N D] = rat(pi);
y = min(N, D);

Здесь, функциональный foo верхнего уровня вызывает внешнюю функцию MATLAB rat, который возвращает два mxArrays, представляющий числитель N и знаменатель D рационального дробного приближения pi. Несмотря на то, что можно передать их mxArrays другой функции MATLAB — в этом случае, min — вы не можете присвоить mxArray, возвращенный min в вывод y.

Если при запуске этот функциональный foo в блоке MATLAB function в модели Simulink®, код генерирует следующую ошибку во время симуляции:

Function output 'y' cannot be of MATLAB type.

Чтобы решить эту проблему, задайте y, чтобы быть типом и размером значения, которое вы ожидаете, что min возвратит — в этом случае, скаляр дважды — можно следующим образом:

function y = foo %#codegen
coder.extrinsic('rat');
[N D] = rat(pi);
y = 0; % Define y as a scalar of type double
y = min(N,D);

Ограничения на внешние функции для генерации кода

Полная среда выполнения MATLAB не поддержана во время генерации кода. Поэтому следующие ограничения применяются при вызове функций MATLAB внешне:

  • Функции MATLAB, которые осматривают вызывающую сторону, или читают или пишут в рабочую область вызывающей стороны, не работают во время генерации кода. Такие функции включают:

  • Отладчик MATLAB не может осмотреть переменные, заданные во внешних функциях.

  • Функции в сгенерированном коде могут привести к непредсказуемым результатам, если ваша внешняя функция выполняет следующие действия во время выполнения:

    • Измените папки

    • Измените путь MATLAB

    • Удалите или добавьте файлы MATLAB

    • Измените предупреждение состояний

    • Измените настройки MATLAB

    • Измените параметры Simulink

  • Генератор кода не поддерживает использование coder.extrinsic, чтобы вызвать функции, которые расположены в частной папке.

  • Генератор кода не поддерживает использование coder.extrinsic, чтобы вызвать локальные функции.

Ограничьте на аргументах функции

Можно вызвать функции максимум с 64 входными параметрами и 64 выходными параметрами.