Page 1 of 1

Microsoft : Understanding Dll's

#1 Martyn.Rae  Icon User is offline

  • The programming dinosaur
  • member icon

Reputation: 540
  • View blog
  • Posts: 1,406
  • Joined: 22-August 09

Posted 22 April 2011 - 05:09 AM

Microsoft : Understanding Dll's

Introduction

Subroutine libraries come in two flavors, namely static libraries and dynamic link libraries. Static libraries are linked into the executable by the linker and form part of the overall executable address space. It is rare to find developers using static link libraries these days, are really are a legacy from days gone by! Dynamic link libraries on the other hand are an essential part of today's development environment. They do not really belong to one specific application as the code part of the library routines is shared between any number of processes using it. They are mapped into the address space of an executable either at load time, or dynamically during the running of a process and can be unmapped from an address space when not needed. This approach saves executable load times as well as huge memory savings through use of shared code rather than individual library copies.

The DLL Reference Counter

Every time the operating system maps a dynamic link library into the address space of an executable process, an internal reference counter is incremented. When the dynamic link library is mapped out of an executable process address space, the reference count is decremented. In this way, the operating system can 'keep track' of dynamic link libraries and not inadvertently remove it from memory when it is in use. Only when the reference counter reaches zero, can a dynamic link library be eligible for removal from physical memory.

DLL Global Variables

A dynamic link library cannot by definition have true global variables, as any data declared outside of function declarations is replicated for each process that maps the library into it's address space. Such variables would be global to a process, but NOT global to the dynamic link library itself.

Thread Local Storage

A dynamic link library can use thread local storage (TLS) to hold variables that need to be local to a thread, rather than the process itself.

DLL Initialization

DLL's have a special entry point that the operating system calls whenever a process maps or unmaps it into an address space. The same entry point is called whenever a process creates a new thread and when a thread exits using the ExitThread API call. This entry point must be called DllMain. The C-Runtime routines do not enforce the need for the developer to provide this function. A default version is used if no DllMain is provided.

If you are compiling without the C runtime routines, then you need to specify the entry point as _DllMainCRTStartup as shown below.

__declspec(dllexport) void __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
}



Accessing Dll Library Routines

Microsoft have been kind enough to provide us with two approaches to using functions in a dynamic link library.

The first approach is to link against a small static library which contains 'stubs' of the routines to be called that satisfy's the linker and stops it from complaining about function declarations that cannot be located. The default is to load such a dynamic link library as part of the executable load process, resolving the 'stub' routine addresses with the correct routine addresses in the library itself. The other approach to this is to tell the linker to generate code such that when a routine is called in a dynamic link library that has not yet been loaded, then the library is loaded and the routine address resolved at that point. This is useful for exception handlers that are not ordinarily needed and would therefore waste memory space. To achieve this, change the executable project settings in Visual Studio under Configuration Properties -> Linker -> Input -> Delay Loaded Dll's.

The second approach is to truly dynamically access the routine programmatically by using Windows API calls. To load a library, you use the LoadLibrary API call. To unload a library when it is no longer required, you call FreeLibrary. To obtain the routine address, you use the GetProcAddress API call.

Is This A Good Question/Topic? 1
  • +

Page 1 of 1