Comparing Static and Dynamic Linking of the Visual Studio 2005 Run-Time Libraries on Windows CE and Windows Mobile

 

Mario Chénier
Microsoft Corporation

August 2005

Applies to:
   Microsoft Windows CE
   Microsoft Visual Studio 2005
   Windows Mobile–based devices

Summary: You will compare static versus dynamic linking the Visual Studio 2005 run-time libraries in native applications that target the Windows CE–based operating system in this article. (4 printed pages)

Contents

Introduction
Dynamic and Static Linking
New Run-Time Libraries in Visual Studio 2005
Static Linking Versus Dynamic Linking on Windows CE
Conclusion

Introduction

Microsoft Visual Studio 2005 includes a C/C++ development environment for Windows Mobile–based and Microsoft Windows CE–based devices. It is the successor to Microsoft eMbedded Visual C++ version 4.0 and enables developers to write C/C++ applications for Microsoft device platforms. As part of the Visual Studio 2005 release, there is an updated version of the Microsoft Foundation Classes (MFC), Active Template Library (ATL), and Standard C++ Library (SCL) for devices, along with a small subset of the Secure C Runtime.

By default, new applications developed with Visual Studio 2005 that target Windows CE–based platforms are configured to statically link the run-time libraries, but there may be times when you should consider explicit dynamic linking against the run-time libraries.

Dynamic and Static Linking

A dynamic-link library (DLL) is an executable file that acts as a shared library of functions. Dynamic linking provides a way for a process to call a function that is not part of its executable code. The executable code for the function is located in a DLL, which contains one or more functions that are compiled, linked, and stored separately from the processes that use them. Only the information needed at run time to locate the executable code for a DLL function is in the executable module (either a .dll or .exe file). These libraries are "dynamically linked" because they are linked to an application when it is loaded and executed — rather than when it is created.

In the case of static linking, the linker gets all of the referenced functions from the static link library and places it with your code into your executable file.

New Run-Time Libraries in Visual Studio 2005

The new device MFC 8.0, ATL 8.0, SCL 8.0 , and CRT 8.0 run-time libraries in Visual Studio 2005 are based the desktop computer versions of these run-time libraries and are subsets based on size, performance, and platform capabilities. They are not factored any differently for the Windows CE, Pocket PC, or Smartphone platforms, so you can rely on the same run-time library functionality for each. The new device run-time libraries do, however, contain some degree of platform awareness. ATL, for example, behaves differently on DCOM than on COM platforms, and it behaves differently on graphical user interface (GUI) platforms than on headless platforms. MFC is user interface (UI) model aware and functions differently on AYGShell than on non–AYGShell platforms.

These run-time libraries are available as both dynamic and static libraries (except SCL, which is only available as a static library), as shown in Table 1.

Table 1. Run-time libraries

Library Link options DLL name ([d] is debug version
"Mini" C runtime 8.0 Static and dynamic Msvcr80[d].dll
ATL 8.0 Static and dynamic Atl80.dll
MFC 8.0 Static and dynamic Mfc80u[d].dll
SCL 8.0 Static only N/A

Static Linking Versus Dynamic Linking on Windows CE

A potential disadvantage to using DLLs is that the application is not self-contained; it depends on the existence of a separate DLL module, and it becomes the application user's responsibility to ensure that the dependent DLL is available on the platform being targeted. For Windows Mobile platforms, MFC 3.0 is in read-only memory (ROM) for backward compatibility, but MFC8.0 is not ensured to be on the device. Therefore, application developers need to ensure that they package the MFC 8.0 runtime with their applications. This approach can cause the full application deliverable to be larger than it would be if the application were statically linked. By statically linking the required run-time libraries into your application, you make the application become a totally self-contained executable. Having a self-contained executable can simplify the process of developing a single application that targets and runs on multiple platforms or multiple versions of an operating system because it reduces the dependency on the additional DLLs.

At process startup time, the system terminates processes that are using dynamic linking — if they require a DLL that is not found at process startup — and displays an error message to the user. The error messages may not be obvious. If the dependent file is not present, you get an error message of the following type: Cannot find 'Application.exe' (or one of its components). Make sure the path and file name are correct and all the required libraries are available. If the DLL is present but does not expose the same set of functionality, the error message is even more cryptic: 'Application.exe' is not a valid Pocket PC application.

Most Windows developers are familiar with the concept DLL versioning conflicts. The concept refers to one of the potential risks of depending on a DLL that can be updated outside your control. When another application updates one of your dependent DLLs, it may be updated with a version that is not compatible with the one you are using. The DLL may be an older or newer version that changes a behavior on which you either explicitly or implicitly depend. On Windows CE–based devices, there is an extra layer of complexity. On the desktop computer version of Win32, you can isolate yourself to some extent by ensuring that the version you built and tested is the one that is loaded by the operating system. One such method is to put the DLL in the same directory as your application, which is the default for Visual Studio 2005. On Windows CE, the loader behaves differently and uses any occurrence found in memory with the matching DLL name. For example, if Application 1 is running and uses a version of the MFC DLL that is in the Application 1 directory, when Application 2 is started, the operating system will use the DLL loaded by Application 1 and will not use the version that is part of Application 2's directory. Similarly, if Application 2 is started first, Application 1 will use Application 2's DLL version. If the versions are not compatible, either Application 1 or Application 2 may behave incorrectly, depending on which application is started first.

Statically linking can, in certain circumstances, make an application run faster. Having the library code statically linked avoids the necessity of loading and initializing the DLL into the application's memory space. The Visual Studio 2005 Linker also supports link-time code generation that can perform optimization that is not available with dynamic linking.

If the application has been dynamically linked and the DLL has been loaded into memory by means of another process, multiple processes share a single copy of the DLL in physical memory. This saves system memory. In contrast, the Windows operating system must load a copy of the consumed library code into memory for each application that is statically linked.

Dynamically linking to the run-time libraries has the benefit that the run-time libraries can be updated with bug fixes or other updates, and the applications that use the run-time library do not need to be recompiled as long as the function APIs remain compatible. In contrast, static linking requires that all applications be relinked to take advantage of the update.

Dynamically linking against MFC also enables you to build your own extensions to MFC library classes and place them in an extension DLL. You are unable to build extension DLLs if you statically link against the MFC runtime libraries.

Dynamically linking can consume less space on the device if multiple components link against MFC. When statically linked, the default Visual Studio 2005 MFC application targeting Windows Mobile–based Pocket PC is approximately an additional 170 kilobyte (KB) in size compared to when it is dynamically linked. Consider that the ARMV4 MFC DLL is approximately 650 KB in size. If you have somewhere between three to five components using the Visual Studio 2005 run time libraries, more space will be consumed on the device than if you were dynamically linking.

Conclusion

There are various issues to consider when deciding whether to statically or dynamically link the Visual Studio 2005 runtimes. There are scenarios for which you should consider dynamically linking against the runtimes. But most commonly it is recommended that you link statically; this is the default behavior for Visual Studio 2005 projects. On most consumer devices, few enough applications are installed, so statically linking will likely reduce memory consumption and likely increase the performance of the component. The extra benefits of static linking such as being able to more easily build and deploy a single application on multiple devices and multiple versions of the Windows operating system will benefit the typical application developer.