7. Using DLLs (Dynamic Modules)

You can not only use DLLs to reduce your program's memory consumption, but also to shorten start times (during which the Nintendo 3DS logo is visible) because only a static module is loaded when the program starts.

7.1. Implementation

If DLLs are not used, you can implement your entire application in a single (main) program. If DLLs are used, you can split your implementation between several dynamic modules that are loaded into memory on demand. If you split your implementation into small dynamic modules that are too fine-grained, however, it will take a long time to load the modules and the frequent switching between modules could complicate memory management.

For more information, see DLL Manual in the CTR-SDK documentation and 3DS Programming Manual: System.

7.2. Preparing to Build

Follow the same procedure described in 4. Preparing to Build.

7.3. Building

7.3.1. Using the CTR-SDK Build System

You can easily build an application that supports dynamic modules by simply paying attention to how your modules' source code is structured and what you put into your OMakefile. Note, however, that a separate build directory must be created for each module, distributing the individual source files and OMakefiles so that the application (static module) has the same parent directory as the dynamic modules.

The following settings have been added to the OMakefile to build dynamic modules.

Table 7-1. Additional Settings for Building Dynamic Modules
Setting Description
TARGET_MODULE Specify the name of the dynamic module.
MODULE_LIST Specify all static and dynamic modules except for this one.
MODULE_EXPORT_TYPE

Specify the type of data that is exported from the dynamic module.

  • SYMBOL: Names (default)
  • INDEX: Indices
  • OFFSET: Offsets
MODULE_ENABLE_OFFSET This has a default value of true, which requires all modules to be built at the same time. When this is false, you can build modules at any time, but you will no longer be able to specify offsets as the type of data to export.
MODULE_ADD_DEBUG_INFO Specifies whether to include the CRO file’s debug information along with the CRR file to be created. The default setting is “true” so source debugging can be performed by the debugger. If the setting is “false”, source debugging cannot be performed. You cannot debug when this is set to false, but the size of the CRR file will be smaller.

You do not need to specify an RSF, ICN, BNR, or DESC files when you build a dynamic module. Note that you specify a dynamic module's name in TARGET_MODULE instead of TARGET_PROGRAM. A CRO file is generated when you build a dynamic module.

Code 7-1. Sample OMakefile for a Dynamic Module
TARGET_MODULE = Module1
MODULE_LIST = ../App ../Module2
SOURCES = module.cpp

include $(ROOT_OMAKE)/modulerules
build:  $(DEFAULT_TARGETS)

To build a static module, simply add MODULE_LIST to the normal build settings. A CRS and CRR file are generated when you build a static module.

Code 7-2. Sample Setting Added to an Application's OMakefile
MODULE_LIST = ../Module1 ../Module2

A ROM archive must include the CRO, CRS, and CRR files that are generated. The CRO and CRS files do not need to be placed anywhere in particular, and they can be either compressed or uncompressed. The .crr directory that is generated directly under the root directory must only contain one uncompressed CRR file and nothing else.

With the following sample OMakefile, OMake will automatically store each file when you build an application that uses dynamic modules.

Code 7-3. Sample OMakefile for Automatically Storing Files in a Dynamic Module
MODULE_NAMES       = Module1 Module2
MODULES_ROOT       = ../

MODULE_CRO         = $(addprefix $(ROMFS_ROOT)/, $(addsuffix .cro, $(MODULE_NAMES)))
STATIC_CRS         = $(ROMFS_ROOT)/static.crs
STATIC_CRR         = $(ROMFS_ROOT)/.crr/static.crr
ROMFS_DEPENDENCIES = $(MODULE_CRO) $`(STATIC_CRS) $`(STATIC_CRR)

foreach(TARGET, $(BUILDER.getTargets $(SUPPORTED_TARGETS)))
    foreach(module, $(MODULE_NAMES))
        src = $(file $(TARGET.getImageDirectoryOf $(MODULES_ROOT)$(module))/$(module).cro)
        dst = $(addprefix $(ROMFS_ROOT)/, $(addsuffix .cro, $(module)))

        $(dst) : $(src)
            cp $< $@

        $(STATIC_CRS): $(TARGET.getImageDirectory false)/$(TARGET_PROGRAM).crs
            cp $< $@

        $(STATIC_CRR): $(TARGET.getImageDirectory false)/$(TARGET_PROGRAM).crr
            mkdir -p $(dirname $@)
            cp $< $@

For more information, see the CTR-SDK Build System Manual (for DLLs).

7.3.2. Using Your Own Build System

To build dynamic modules without using the build system provided by the CTR-SDK, you must add partial linking, symbol resolution, and other special processing.

For more information, see Guide to Developing a Build System (for DLLs) in the CTR-SDK documentation.

7.4. Debugging

When building an application, source debugging can be performed using the debugger if the CRO file’s debug information is included along with the CRR file.

For more information about the methods of including the CRO file’s debug information with the CRR file, see 7.3.1. Using the CTR-SDK Build System and the CTR-SDK Build System Manual (for DLLs).


CONFIDENTIAL