MATLAB Examples

Build 32-bit DLL on 64-bit Windows® Platform Using MSVC Toolchain

Register and use a Microsoft® Visual C/C++ (MSVC) toolchain running on a 64-bit Windows® platform to compile a 32-bit dynamic link library (DLL). This example uses a Microsoft® compiler. However, the concepts and programming interface apply for other toolchains. Once you register the toolchain, you can select it from a list of toolchains, and the code generator generates a makefile to build the code by using that toolchain. A toolchain consists of several tools, such as a compiler, linker, and archiver with multiple different configuration options. The toolchain compiles, links, and runs code on a specified platform. To access the files that this example uses, click Open Script.

Contents

Check Platform and Determine MSVC Version

This code checks that the platform is supported and that you have a supported version of Microsoft® Visual C/C++. The my_msvc_32bit_tc.m toolchain definition can use the Microsoft® Visual Studio versions 7.1, 9.0, 10.0, 11.0, 12.0, 14.0, or 15.0.

If you are not using a Windows® platform, or if you do not have a supported version of Microsoft® Visual C/C++, the example generates only code and a makefile, without running the generated makefile.

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');
    if isempty(MSVC_InstalledVersions)
        supportedCompilerInstalled = false;
    else
        VersionNumbers = {installed_compilers(cellfun(@(a)~isempty(a), MSVC_InstalledVersions)).Version}';
        supportedCompilerInstalled = true;
    end
end

Function for the Dynamic Link Library

The example function for the dynamic link library, myMatlabFunction.m, multiplies a number by two.

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

Create and Configure an MSVC Toolchain

The my_msvc_32bit_tc.m toolchain definition function takes in an argument containing the Visual Studio version number. In this example, the commands that create and configure this toolchain are:

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

Register the Toolchain

Before the code generator can use a toolchain for the build process, the RTW.TargetRegistry must contain the toolchain registration. This registration can come from any rtwTargetInfo.m file on the MATLAB path. MATLAB will load a new registration if the RTW.TargetRegistry is reset.

Create the rtwTargetInfo.m file from the corresponding text file 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');

Create Code Generation Configuration Object

To generate the 32-bit dynamic link library (DLL), create a 'dll' code generation configuration object. Specifying 'dll' directs the linker (a build tool in the toolchain) to use "Shared Library" linker commands.

cfg = coder.config('dll');

Configure Code Generation for 32-bit Hardware

To successfully generate code that is compatible with 32-bit hardware, the generated code must use the correct underlying C types (for example, int, signed char, and others). These types are the basis for typedef statements for sized types (for example, uint8, int16, and others). Set the configuration with the command:

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

Configure Code Generation to Use the 32-bit Toolchain

Set the name of the Toolchain property to match the Name that you specify in the rtwTargetInfo.m file.

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

Select Verbose Status Reporting

To provide confirmation of compiler flags that the toolchain uses to build the DLL, select verbose status reporting.

cfg.Verbose = true;

Determine Whether to Generate Code Only

When the Microsoft® compilers are not installed, the code generator generates only code and the makefile. When the supported compilers are installed, the code generator builds the 32-bit binary file.

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

Generate Code and Build a DLL

To use the toolchain for code generation and build the DLL (if build is enabled), at the command prompt, enter:

codegen -config cfg myMatlabFunction -args { double(1.0) };
### Using toolchain: Microsoft Visual C++ 2015 (32 bit) | 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>call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\..\..\VC\vcvarsall.bat" amd64_x86  
 
Microsoft (R) Program Maintenance Utility Version 14.00.24210.0 
Copyright (C) Microsoft Corporation.  All rights reserved. 
 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"myMatlabFunction_initialize.obj" "H:\examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_initialize.c" 
myMatlabFunction_initialize.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"myMatlabFunction_terminate.obj" "H:\examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_terminate.c" 
myMatlabFunction_terminate.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"myMatlabFunction.obj" "H:\examples\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction.c" 
myMatlabFunction.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"rt_nonfinite.obj" "H:\examples\coder-ex19875030\codegen\dll\myMatlabFunction\rt_nonfinite.c" 
rt_nonfinite.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"rtGetNaN.obj" "H:\examples\coder-ex19875030\codegen\dll\myMatlabFunction\rtGetNaN.c" 
rtGetNaN.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"rtGetInf.obj" "H:\examples\coder-ex19875030\codegen\dll\myMatlabFunction\rtGetInf.c" 
rtGetInf.c 
	E:\JOBARC~1\Bdoc17b\2LQECH~T\matlab\bin\win64\createResponseFile.exe 1 myMatlabFunction.rsp myMatlabFunction_initialize.obj myMatlabFunction_terminate.obj myMatlabFunction.obj rt_nonfinite.obj rtGetNaN.obj rtGetInf.obj 
### Creating dynamic library ".\myMatlabFunction.dll" ... 
	link /DEBUG /DEBUGTYPE:cv  /INCREMENTAL:NO /NOLOGO -subsystem:console,5.02 kernel32.lib ws2_32.lib mswsock.lib advapi32.lib  -dll -def:myMatlabFunction.def -out:.\myMatlabFunction.dll @myMatlabFunction.rsp   
   Creating library .\myMatlabFunction.lib and object .\myMatlabFunction.exp 
### Created: .\myMatlabFunction.dll 
### Successfully generated all binary outputs. 

Build and Run an Executable

If you have a supported version of the compiler installed, you can build the 32-bit executable by using a C main function. You can use the executable to test that the generated code works as expected.

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
    system('myMatlabFunction 3.1416'); % Expected output: myMatlabFunction(3.1416) = 6.2832
end
### Using toolchain: Microsoft Visual C++ 2015 (32 bit) | 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>call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\..\..\VC\vcvarsall.bat" amd64_x86  
 
Microsoft (R) Program Maintenance Utility Version 14.00.24210.0 
Copyright (C) Microsoft Corporation.  All rights reserved. 
 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"myMatlabFunction_initialize.obj" "H:\examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_initialize.c" 
myMatlabFunction_initialize.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"myMatlabFunction_terminate.obj" "H:\examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_terminate.c" 
myMatlabFunction_terminate.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"myMatlabFunction.obj" "H:\examples\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction.c" 
myMatlabFunction.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"rt_nonfinite.obj" "H:\examples\coder-ex19875030\codegen\exe\myMatlabFunction\rt_nonfinite.c" 
rt_nonfinite.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"rtGetNaN.obj" "H:\examples\coder-ex19875030\codegen\exe\myMatlabFunction\rtGetNaN.c" 
rtGetNaN.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"rtGetInf.obj" "H:\examples\coder-ex19875030\codegen\exe\myMatlabFunction\rtGetInf.c" 
rtGetInf.c 
	cl -c -DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo -GS -D_AMD64_=1 -DWIN64 -D_WIN64 -DWIN32 -D_WIN32 -W4 -D_WINNT -D_WIN32_WINNT=0x0502 -DNTDDI_VERSION=0x05020000 -D_WIN32_IE=0x0600 -DWINVER=0x0502 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /Od /Oy- -DMODEL=myMatlabFunction -DHAVESTDIO -DUSE_RTMODEL -Fo"myMatlabFunction_main.obj" "H:\examples\coder-ex19875030\myMatlabFunction_main.c" 
myMatlabFunction_main.c 
	E:\JOBARC~1\Bdoc17b\2LQECH~T\matlab\bin\win64\createResponseFile.exe 1 myMatlabFunction.rsp myMatlabFunction_initialize.obj myMatlabFunction_terminate.obj myMatlabFunction.obj rt_nonfinite.obj rtGetNaN.obj rtGetInf.obj myMatlabFunction_main.obj 
### Creating standalone executable "H:\examples\C7WFRE~L\myMatlabFunction.exe" ... 
	link /DEBUG /DEBUGTYPE:cv  /INCREMENTAL:NO /NOLOGO -subsystem:console,5.02 kernel32.lib ws2_32.lib mswsock.lib advapi32.lib -out:H:\examples\C7WFRE~L\myMatlabFunction.exe @myMatlabFunction.rsp   
### Created: H:\examples\C7WFRE~L\myMatlabFunction.exe 
### Successfully generated all binary outputs. 
myMatlabFunction(3.1416) = 6.2832 

Optional Step: Unregister the toolchain

To unregister the toolchain, enter:

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