Hi Peter, * Peter Rosin wrote on Wed, Oct 13, 2010 at 08:19:27PM CEST: > Can you spot any errors?
See below. I've only checked for things obvious to me; I hope somebody else verifies the w32 semantics and details. ;-) Thanks for writing this! > (I have not actually tested the code samples. Yet) Thanks in advance! :-) > Windows DLLs. > ------------- > > This topic describes a couple of ways to portably create Windows Dynamic > Link Libraries (DLLs). Libtool knows how to create DLLs using GNU tools Two spaces after period. > and using Microsoft tools. > > A typical library has a "hidden" implementation with an interface > described in a header file. On just about every system, the interface > could be something like this: > > Example foo.h: > > #ifndef FOO_H > #define FOO_H > > int one (void); > int two (void); > extern int three; > > #endif /* FOO_H */ > > And the implementation could be something like this: > > Example foo.c: > > #include "foo.h" > > int one (void) > { > return 1; > } > > int two (void) > { > return 2; > } > > int three = 3; Isn't this less-than fully general, in the sense that having in addition references to one and three from within two would possibly be more complex to handle? > When using contemporary GNU tools to create the Windows DLL, the above > code will work there too, thanks to its auto-import/auto-export > features. But that is not the case when using older GNU tools or perhaps > more interesting when using proprietary tools. In those cases the code > will need additional decorations on the interface symbols with > __declspec(dllimport) and __declspec(dllexport) depending on if the > library is built or if it's consumed and how it's built and consumed. > > Concentrating on how Libtool is using Microsoft tools, Libtool will dig How about simplifying this to With Microsoft tools, Libtool will dig ... > through the object files making up the library looking for non-static that make up the > symbols to automatically export. I.e., Libtool with Microsoft tools is > trying to mimic the auto-export feature of the contemporary GNU tools. > It should be noted that the GNU auto-export feature in turned off when s/ in / is / > an explicit __declspec(dllexport) is seen. The GNU tools is doing this s/is doing/do/ or s/is/are/ > to not make more symbols visible for projects that have already taken > the trouble to decorate all symbols. There is no similar way to limit s/all// ? (because how can you know that it did do so for all symbols, when parts of the project may come from third parties?) > which symbols are visible in the code when Libtool is using Microsoft > tools. In order to limit symbol visibility in that case you need to use > one of the -export-symbols or -export-symbols-regex options. > > No matching help with auto-import is provided by Libtool for neither > proprietary tools nor older GNU tools, so symbols *must* be decorated in > order to import them from a DLL for everything but contemporary GNU > tools on Windows. But can we not assume that older GNU tools are irrelevant? What would keep people from updating them? > When the objects that form the library are built, there are generally > two copies built for each object. One copy is used when linking the DLL > and one copy is used for the static library. On Windows systems, the > copy used when creating the DLL is compiled with the flag -DDLL_EXPORT. > It is common practice to also add a flag that is only present when the > library is built, but that will not be present when it is consumed, such > as -DBUILDING_LIBFOO. These defines are then used to discriminate how > the interface symbols should be decorated. This seems to be a bit reversed. From a narrative standpoint, the "common practice" only appears out of necessity, and the necessity has not been explained yet. Right? > However, the matching double compile is not performed when consuming > libraries. It is therefore not possible to reliably distinguish if the > consumer is importing from a DLL or if it is going to use a static > library. With contemporary GNU tools, auto-import saves the day. because auto-import does what exactly? (pointer to auto-import documentation from binutils?) > With > Microsoft tools you typically get away with always compiling the code as > if it is going to be linked with a DLL. There are cases when this does > not work, such as when only variables and no functions are imported from > the library. There is also a price connected to this liberal use of > imports in that an extra indirection is introduced when you are > consuming the static version of the library. That extra indirection is > always present when the DLL is consumed, but it is not needed when > consuming the static library. This paragraph is fairly vague. I understand if you don't want to tell all the gory details about this, but in that case maybe a pointer to more detailed documentation would be good here. > For older GNU tools and other proprietary tools there is no generic way > to make it possible to consume either of the DLL or the static library > without user intervention, the tools needs to be told what is intended. > Or, to be exact, the author are not aware of any generic way. One s/are/is/ This sounds a bit awkward still. > assumption that has been used is that if a DLL is being built that is commonly used? > (DLL_EXPORT is defined) then that DLL is going to consume any dependent > libraries as DLLs. If that assumption is made everywhere, it is possible > to select how an end user application is consuming libraries by adding a end-user > single flag -DDLL_EXPORT when a DLL build is required. This is of course > an all or nothing deal, either everything as DLLs or everything as > static libraries. > > To sum up the above, the header file of the foo library needs to be > changed into something like this: > > Modified foo.h: > > #ifndef FOO_H > #define FOO_H > > #if (defined _WIN32 || defined _WIN32_WCE) && !defined __GNUC__ > # ifdef BUILDING_LIBFOO > # ifdef DLL_EXPORT > # define LIBFOO_SCOPE extern __declspec (dllexport) > # endif > # elif defined _MSC_VER || defined DLL_EXPORT > # define LIBFOO_SCOPE extern __declspec (dllimport) > # endif > #endif > #ifndef LIBFOO_SCOPE > # define LIBFOO_SCOPE extern > #endif > > LIBFOO_SCOPE int one (void); > LIBFOO_SCOPE int two (void); > LIBFOO_SCOPE int three; > > #endif /* FOO_H */ > > It should be noted that there are various projects that attempt to relax > these requirements by various low level tricks, but they are not > discussed here. Pointers? Cheers, Ralf _______________________________________________ http://lists.gnu.org/mailman/listinfo/libtool