Создайте 32-разрядную библиотеку DLL на 64-разрядной платформе Windows ® с помощью набора инструментальных средств MSVC

Зарегистрируйте и используйте набор инструментов Microsoft ® Visual C/C + + (MSVC), работающий на 64-разрядной платформе Windows ®, чтобы скомпилировать 32-разрядную библиотеку динамических ссылок (DLL). Этот пример использует компилятор Microsoft ®. Однако концепции и программный интерфейс применяются к другим цепочкам инструментов. После регистрации набора инструментальных средств можно выбрать его из списка наборов инструментальных средств, и генератор кода генерирует make-файл, чтобы создать код при помощи этого набора инструментальных средств. Набор инструментальных средств состоит из нескольких инструментов, таких как компилятор, линкер и архиватор с несколькими различными опциями строения. Набор инструментальных средств компилирует, связывает и запускает код на указанной платформе. Чтобы получить доступ к файлам, которые использует этот пример, нажмите Open Script.

Проверяйте платформу и определяйте версию MSVC

Этот код проверяет поддержку платформы и наличие поддерживаемой версии Microsoft ® Visual C/C + +. The my_msvc_32bit_tc.m в определении набора инструментальных средств могут использоваться версии Microsoft ® Visual Studio 9.0, 10.0, 11.0, 12.0, 14.0 или 15.0.

Если вы не используете платформу Windows ® или у вас нет поддерживаемой версии Microsoft ® Visual C/C + +, то в примере генерируется только код и make-файл, не запуская сгенерированный make-файл.

VersionNumbers = {'14.0'}; % Placeholder value
if ~ispc
    supportedCompilerInstalled = false;
else
    installed_compilers = mex.getCompilerConfigurations('C', 'Installed');
    MSVC_InstalledVersions = regexp({installed_compilers.Name}, 'Microsoft Visual C\+\+ 20\d\d');
    MSVC_InstalledVersions = cellfun(@(a)~isempty(a), MSVC_InstalledVersions);
    if ~any(MSVC_InstalledVersions)
        supportedCompilerInstalled = false;
    else
        VersionNumbers = {installed_compilers(MSVC_InstalledVersions).Version}';
        supportedCompilerInstalled = true;
    end
end

Функция для библиотеки динамических ссылок

Область функции , взятой в качестве примера, для библиотеки динамических ссылок, myMatlabFunction.m, умножает число на два.

function y = myMatlabFunction(u) 
% myMatlabFunction: Returns twice its input.
% Copyright 2017 The MathWorks, Inc.

%#codegen
assert(isa(u, 'double'), 'The input must be a "double".');
assert(all([1, 1] == size( u )), 'The input must be a scalar.');

y = double(u + u);

Создайте и сконфигурируйте набор инструментальных средств MSVC

The my_msvc_32bit_tc.m Функция определения набора инструментальных средств принимает аргумент, содержащий номер версии Visual Studio. В этом примере команды, которые создают и конфигурируют этот набор инструментальных средств:

tc = my_msvc_32bit_tc(VersionNumbers{end});
save my_msvc_32bit_tc tc;
Executing "H:\Examples\coder-ex19875030\my_msvc_32bit_tc"...
Executed "H:\Examples\coder-ex19875030\my_msvc_32bit_tc".

Зарегистрируйте набор инструментальных средств

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

Создайте rtwTargetInfo.m файл из соответствующего текстового файла myRtwTargetInfo.txt.

function myRtwTargetInfo(tr)
%RTWTARGETINFO Registration file for custom toolchains.

% Copyright 2012-2017 The MathWorks, Inc.

tr.registerTargetInfo(@createToolchainRegistryFor32BitMSVCToolchain);

end

% -------------------------------------------------------------------------
% Create the ToolchainInfoRegistry entries
% -------------------------------------------------------------------------
function config = createToolchainRegistryFor32BitMSVCToolchain

config(1)                       = coder.make.ToolchainInfoRegistry;
config(1).Name                  = 'Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)';
config(1).FileName              = fullfile(fileparts(mfilename('fullpath')), 'my_msvc_32bit_tc.mat');
config(1).TargetHWDeviceType    = {'Intel->x86-32 (Windows32)','AMD->x86-32 (Windows32)','Generic->Unspecified (assume 32-bit Generic)'};
config(1).Platform              =  {'win64'};

end
copyfile myRtwTargetInfo.txt rtwTargetInfo.m
RTW.TargetRegistry.getInstance('reset');

Создайте объект строения генерации кода

Чтобы сгенерировать 32-битную библиотеку динамических ссылок (DLL), создайте 'dll' объект строения генерации кода. Определение 'dll' указывает linker (инструмент сборки в наборе инструментальных средств) использовать команды linker «Общая библиотека».

cfg = coder.config('dll');

Сконфигурируйте генерацию кода для 32-разрядного оборудования

Чтобы успешно сгенерировать код, который совместим с 32-битным оборудованием, сгенерированный код должен использовать правильные базовые типы C (для примера int, signed char, и др.). Эти типы являются базисом для typedef операторы для типоразмеров (для примера, uint8, int16, и др.). Настройте строение командой:

cfg.HardwareImplementation.ProdHWDeviceType = ...
    'Generic->Unspecified (assume 32-bit Generic)';

Сконфигурируйте генерацию кода, чтобы использовать 32-разрядный набор инструментальных средств

Установите имя Toolchain свойство, соответствующее Name что вы задаете в rtwTargetInfo.m файл.

cfg.Toolchain = ...
    'Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)';

Выбор подробных отчетов о состоянии

Чтобы предоставить подтверждение флагов компилятора, которые набор инструментальных средств использует для создания DLL, выберите подробные отчеты о состоянии.

cfg.Verbose = true;

Определите, нужно ли генерировать только код

Когда компиляторы Microsoft ® не установлены, генератор кода генерирует только код и make-файл. Когда поддерживаемые компиляторы установлены, генератор кода создает 32-разрядный двоичный файл.

if supportedCompilerInstalled
    cfg.GenCodeOnly = false;
else
    cfg.GenCodeOnly = true;
end

Сгенерируйте код и создайте DLL

Чтобы использовать набор инструментов для генерации кода и создать DLL (если сборка включена), в командной строке введите:

codegen -config cfg myMatlabFunction -args { double(1.0) };
### Using toolchain: Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)
### Creating 'H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_rtw.mk' ...
### Building 'myMatlabFunction': nmake  -f myMatlabFunction_rtw.mk all
 
H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction>set "VSCMD_START_DIR=H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction"  
 
H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction>call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\\VC\Auxiliary\Build\vcvarsall.bat" amd64_x86  
********************************************************************** 
** Visual Studio 2017 Developer Command Prompt v15.0.26730.12 
** Copyright (c) 2017 Microsoft Corporation 
********************************************************************** 
[vcvarsall.bat] Environment initialized for: 'x64_x86' 
 
Microsoft (R) Program Maintenance Utility Version 14.11.25507.1 
Copyright (C) Microsoft Corporation.  All rights reserved. 
 
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy-  -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_initialize.obj" "H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_initialize.c" 
myMatlabFunction_initialize.c 
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy-  -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_terminate.obj" "H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_terminate.c" 
myMatlabFunction_terminate.c 
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy-  -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction.obj" "H:\Examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction.c" 
myMatlabFunction.c 
### Creating dynamic library ".\myMatlabFunction.dll" ... 
	link /MACHINE:X86 /DEBUG /DEBUGTYPE:cv  /INCREMENTAL:NO /NOLOGO kernel32.lib ws2_32.lib mswsock.lib advapi32.lib  -dll -def:myMatlabFunction.def -out:.\myMatlabFunction.dll @myMatlabFunction_rtw.rsp   
   Creating library .\myMatlabFunction.lib and object .\myMatlabFunction.exp 
### Created: .\myMatlabFunction.dll 
### Successfully generated all binary outputs. 

Создайте и запустите исполняемый файл

Если у вас установлена поддерживаемая версия компилятора, можно создать 32-битный исполняемый файл с помощью основной функции на C. Можно использовать исполняемый файл, чтобы проверить, что сгенерированный код работает должным образом.

cfge = coder.config('exe');
cfge.CustomInclude = pwd;
cfge.CustomSource = 'myMatlabFunction_main.c';
cfge.GenCodeOnly = cfg.GenCodeOnly;
cfge.Verbose = true;
cfge.Toolchain = ...
    'Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)';
codegen -config cfge myMatlabFunction -args { double(1.0) };
if supportedCompilerInstalled
    pause(5); %wait for EXE to get generated
    system('myMatlabFunction 3.1416'); % Expected output: myMatlabFunction(3.1416) = 6.2832
end
### Using toolchain: Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)
### Creating 'H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_rtw.mk' ...
### Building 'myMatlabFunction': nmake  -f myMatlabFunction_rtw.mk all
 
H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction>set "VSCMD_START_DIR=H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction"  
 
H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction>call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\\VC\Auxiliary\Build\vcvarsall.bat" amd64_x86  
********************************************************************** 
** Visual Studio 2017 Developer Command Prompt v15.0.26730.12 
** Copyright (c) 2017 Microsoft Corporation 
********************************************************************** 
[vcvarsall.bat] Environment initialized for: 'x64_x86' 
 
Microsoft (R) Program Maintenance Utility Version 14.11.25507.1 
Copyright (C) Microsoft Corporation.  All rights reserved. 
 
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy-  -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_initialize.obj" "H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_initialize.c" 
myMatlabFunction_initialize.c 
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy-  -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_terminate.obj" "H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_terminate.c" 
myMatlabFunction_terminate.c 
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy-  -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction.obj" "H:\Examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction.c" 
myMatlabFunction.c 
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy-  -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_main.obj" "H:\Examples\coder-ex19875030\myMatlabFunction_main.c" 
myMatlabFunction_main.c 
### Creating standalone executable "H:\Examples\coder-ex19875030\myMatlabFunction.exe" ... 
	link /MACHINE:X86 /DEBUG /DEBUGTYPE:cv  /INCREMENTAL:NO /NOLOGO kernel32.lib ws2_32.lib mswsock.lib advapi32.lib -out:H:\Examples\coder-ex19875030\myMatlabFunction.exe @myMatlabFunction_rtw.rsp   
### Created: H:\Examples\coder-ex19875030\myMatlabFunction.exe 
### Successfully generated all binary outputs. 
myMatlabFunction(3.1416) = 6.2832 

Необязательный шаг: Отмена регистрации набора инструментальных средств

Чтобы отменить регистрацию набора инструментальных средств, введите:

delete ./rtwTargetInfo.m
RTW.TargetRegistry.getInstance('reset');

Похожие темы