Main Content

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

Note: To simply produce a 32-bit DLL on Windows® with Microsoft® Visual Studio installed, use a CMake toolchain like Microsoft Visual Studio Project 2017 | CMake (32-bit Windows). This page documents how you can author a custom toolchain to change compiler options and integrate new compilers. For more information on building generated code with CMake, see Configure CMake Build Process.

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.

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

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 "C:\Users\mamlicke\OneDrive - MathWorks\Documents\MATLAB\ExampleManager\mamlicke.Bdoc24a.j2373701\coder-ex19875030\my_msvc_32bit_tc"...
Executed "C:\Users\mamlicke\OneDrive - MathWorks\Documents\MATLAB\ExampleManager\mamlicke.Bdoc24a.j2373701\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) };
### Compiling function(s) myMatlabFunction ...
------------------------------------------------------------------------
### Using toolchain: Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)
### 'C:\Users\mamlicke\OneDrive - MathWorks\Documents\MATLAB\ExampleManager\mamlicke.Bdoc24a.j2373701\coder-ex19875030\codegen\dll\myMatlabFunction\myMatlabFunction_rtw.mk' is up to date
### Building 'myMatlabFunction': nmake  -f myMatlabFunction_rtw.mk all
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.11.7
** Copyright (c) 2021 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64_x86'

Microsoft (R) Program Maintenance Utility Version 14.29.30137.0
Copyright (C) Microsoft Corporation.  All rights reserved.

	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /O2 /Oy-  -DMODEL=myMatlabFunction @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_initialize.obj" "C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\codegen\dll\myMatlabFunction\myMatlabFunction_initialize.c"
myMatlabFunction_initialize.c
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /O2 /Oy-  -DMODEL=myMatlabFunction @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_terminate.obj" "C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\codegen\dll\myMatlabFunction\myMatlabFunction_terminate.c"
myMatlabFunction_terminate.c
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /O2 /Oy-  -DMODEL=myMatlabFunction @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction.obj" "C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\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.


------------------------------------------------------------------------
Code generation successful.

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
    pause(5); %wait for EXE to get generated
    system('myMatlabFunction 3.1416'); % Expected output: myMatlabFunction(3.1416) = 6.2832
end
### Compiling function(s) myMatlabFunction ...
------------------------------------------------------------------------
### Using toolchain: Microsoft 32 Bit Toolchain | nmake makefile (64-bit Windows)
### 'C:\Users\mamlicke\OneDrive - MathWorks\Documents\MATLAB\ExampleManager\mamlicke.Bdoc24a.j2373701\coder-ex19875030\codegen\exe\myMatlabFunction\myMatlabFunction_rtw.mk' is up to date
### Building 'myMatlabFunction': nmake  -f myMatlabFunction_rtw.mk all
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.11.7
** Copyright (c) 2021 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64_x86'

Microsoft (R) Program Maintenance Utility Version 14.29.30137.0
Copyright (C) Microsoft Corporation.  All rights reserved.

	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /O2 /Oy-  -DMODEL=myMatlabFunction @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_main.obj" "C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\myMatlabFunction_main.c"
myMatlabFunction_main.c
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /O2 /Oy-  -DMODEL=myMatlabFunction @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_initialize.obj" "C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\codegen\exe\myMatlabFunction\myMatlabFunction_initialize.c"
myMatlabFunction_initialize.c
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /O2 /Oy-  -DMODEL=myMatlabFunction @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction_terminate.obj" "C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\codegen\exe\myMatlabFunction\myMatlabFunction_terminate.c"
myMatlabFunction_terminate.c
	cl  -c -nologo -GS -W4 -DWIN32 -D_MT -MTd -D_CRT_SECURE_NO_WARNINGS  /O2 /Oy-  -DMODEL=myMatlabFunction @myMatlabFunction_rtw_comp.rsp -Fo"myMatlabFunction.obj" "C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\codegen\exe\myMatlabFunction\myMatlabFunction.c"
myMatlabFunction.c
### Creating standalone executable "C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\myMatlabFunction.exe" ...
	link /MACHINE:X86 /DEBUG /DEBUGTYPE:cv  /INCREMENTAL:NO /NOLOGO kernel32.lib ws2_32.lib mswsock.lib advapi32.lib -out:C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\myMatlabFunction.exe @myMatlabFunction_rtw.rsp  
### Created: C:\Users\mamlicke\ONEDRI~1\DOCUME~1\MATLAB\EXAMPL~1\MAMLIC~2.J23\CODER-~1\myMatlabFunction.exe
### Successfully generated all binary outputs.


------------------------------------------------------------------------
Code generation successful.

myMatlabFunction(3.1416) = 6.2832 

Optional Step: Unregister the toolchain

To unregister the toolchain, enter:

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

Related Topics