Thursday, January 14, 2010

The Way of DLL and Lib

(Jan 14, 2010)

Why do we need both .lib and .dll at the same time?

Today, I helped my friends figure some build and run-time problems in Visual Studio 2008.  I'm not familiar with these problems at all, but I can draw some important conclusions that I earlier did not realized.  It is about the usage of lib and DLL with and without source code of the library.  Earlier, I created several projects and made them static libraries.  Then, a few executable projects utilized them inside the same solution tree within Visual Studio 2008 development environment.  These executable projects can be run without the presence of DLL at all.

However, when I worked with freeglut.lib, a tool kit for OpenGL, I needed freeglut.dll during run-time, even though I planned to statically linked my project with freeglut.lib.  This is opposite to what I expected, but understandable.  If we do not have source code in the same solution tree, the compiler/linker does not have enough information about what should be incorporated into an executable file.  Therefore, only .lib stub/proxy is employed during linking and actual implementation is found during run-time.

Another question is "So, why can't we have only .dll and throw away all .lib files when we are going to use the .dll via dynamic linking?"

A few reasons are elaborated at 'stackoverflow' website.  The strongest reason may be '.lib manifest files allow us to work with different versions of DLLs in our system' and 'Native DLL's do not have strong names, so it may be possible to pick up the wrong version of the DLL'.  However, it seems possible to link with only DLL by using some other work (shown in the same page of stackoverflow).  The limitation of stand-alone DLL probably comes from an old design of compiler/linker/operating system (run-time platform), as it is pointed out that MS .Net can do this.

Tuesday, January 12, 2010

C++ Template in Shared Library/DLL

(Jan 12, 2010)

Using a C++ template in a shared library or DLL across the library boundary is not permitted, as all class and method definition must be available at the compile time if a template class or method is to be exported.  Therefore, the template class/method must be exclusively utilized within the shared library/DLL and should not declared AFX_EXT_CLASS or __declspec( dllexport ) for Visual C++.

For your information, Macro AFX_EXT_CLASS does not have the same meaning all the time.  In fact, it depends on preprocessor symbols.  From MSDN, it is stated that

"This macro is defined by MFC as __declspec(dllexport) when the preprocessor symbols _AFXDLL and _AFXEXT are defined. But the macro is defined as __declspec(dllimport) when _AFXDLL is defined and _AFXEXT is not defined. When defined, the preprocessor symbol _AFXDLL indicates that the shared version of MFC is being used by the target executable (either a DLL or an application). When both _AFXDLL and _AFXEXT are defined, this indicates that the target executable is an extension DLL."

This may be a good idea to have one header that can work as both dllexport and dllimport, depending on usage.  However, this may cause confusion to a new comer until he or she realizes how AFX_EXT_CLASS works.  Moreover, I still wonder what will happen if a DLL uses another DLL because header files from both DLLs have AFX_EXT_CLASS, but it has different meaning due to dual contexts. 

Microsoft discusses this in their own web site:  In short, this is a limitation for the use of AFX_EXT_CLASS.  The issue in the above example can be solved by using a directive for each library.  For example, suppose there are two DLLs: abc.dll and def.dll.  Header files for abc.dll has a directive #define ABC_DLL_IMEXPORT __declspec(dllexport) or __declspec(dllimport), depending on usage context, while header files for def.dll has #define DEF_DLL_IMEXPORT __declspec(dllexport) or __declspec(dllimport).