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: http://support.microsoft.com/kb/128199.  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). 

No comments: