Minimal Dynamic Library Support

Lawrence Crowl, 2006-10-19, N2117=06-0187

Introduction

The construction and use of dynamic libraries has become a significant requirement on modern software development. Unforutunatly, their interaction with C++ varies between implementations and is often underspecified on any given implementation.

This paper outlines a proposal that addresses these problems. The proposal is based on prior art, the Sun (and by extension System V) and Microsoft platforms.

Library Dependence

When a dynamic library is statically linked, the programmer may specify a list of other dynamic libraries, upon which the current library depends.

Symbol Visibility

The first feature required is a means to control the visibility of function, variable, and class symbols to references in other dynamic libraries. There are these categories of visibility.

hidden
A symbol definition is not visible to other dynamic libraries. A symbol reference must bind to a definition within the same dynamic library.
protected, symbolic, dllexport
A symbol definition is visible to other dynamic libraries. A symbol reference must bind to a definition within the same dynamic library.
dllimport
This visibility does not support symbol definitions. A symbol reference must bind to a definition within one of the dependent libraries.
noninterposable
This visibility does not support symbol definitions. A symbol reference binds to a definition within the same dynamic library, if such a definition is available, otherwise it binds to a definition within one of the dependent libraries.
global, interposable
A symbol definition is visibile to other dynamic libraries. A symbol reference must bind to the definition within the list of dependent libraries of the executable. This visibility is not directly supported on the Microsoft platform, but is required by the C++ standard for operators new and delete.

The Unix default visibility for symbol definitions is global/interposable. The Microsoft default is hidden. The principle of least exposure says the default should be hidden.

The Unix default visibility for symbol references is global. The Microsoft default is hidden. Again, the principle of least exposure says the default should be hidden. However, this default essentially makes it impossible to share a header between the client of a library and the implementation of a library and to use existing headers. Therefore, the proposed default for references is noninterposable.

In order to handle symbol declaration in a common header and a definition within the library, symbols may be redeclared with a more restrictive visibility.

Syntactically, these visibilities most naturally match storage classes.

One-Definition Rule

The one-definition rule must be modified somewhat to make hidden visibility viable. In particular, the one-definition rule must apply to symbols defined within a dynamic library, to symbols referenceable from other dynamic libraries. A consequence of this rule is that hidden types must yield typeids unique to the dynamic library of its definition.

Dynamic Library Open and Close

The opening of a dynamic library will execute the dynamic initializers for namespace-scope static-duration variables defined within the dynamic library. The opening of a library will not return until the initialization is complete.

The closing of a dynamic library will execute the destructors for namespace-scope static-duration variables defined within the dynamic library. The closing of a library will not return until the destruction is complete.