c++windowsdlldllimportafx

Unresolved external on static data member from another DLL


Consider the following source of From.dll library defining the From class:

Header:

// From.h
#include <afxwin.h>
#include <afxext.h>

class AFX_EXT_CLASS From
{
    public:
        static const char staticMember[666];
};

Implementation:

// From.cpp
#include "From.h"

const char From::staticMember[] = "Total Crap";

This library static member staticMember must be used from the following To class, which must also give rise to a DLL (To.dll):

Header:

// To.h
#include <afxwin.h>
#include <afxext.h>

class AFX_EXT_CLASS To
{
    public:
        static const char* retExtStatic();
};

Implementation:

// To.cpp
#include "To.h"
#include "From.h"

const char* To::retExtStatic()
{
    return From::staticMember;
}

But I keep getting this LNK2001: unresolved external symbol "public: static char const * const From::staticMember" (?staticMember@From@@2QBDB) when linking To.dll, no matter if it's directly on Visual Studio or if it's a cmake generated nmake:

Linking CXX shared library To.dll
   Creating library To.lib and object To.exp
To.cpp.obj : error LNK2001: unresolved external symbol "public: static char const * const From::staticMember" (?staticMember@From@@2QBDB)
To.dll : fatal error LNK1120: 1 unresolved externals

The first DLL is compiled and linked allright. The following are the relevant parts of my CMakeLists.txt:

add_definitions (-D_AFXDLL -D_AFXEXT -DPSAPI_VERSION=1)
set (CMAKE_MFC_FLAG 2) # Use MFC in a shared DLL

# FROM
file (GLOB FROM ${CMAKE_CURRENT_SOURCE_DIR}/From.cpp)
add_library (From SHARED ${FROM})
target_link_libraries (From)

# TO
file (GLOB TO ${CMAKE_CURRENT_SOURCE_DIR}/To.cpp)
add_library (To SHARED ${TO})
target_link_libraries (To From)

What am I doing wrong to export this static data member?


Solution

  • As @Niall and @Igor Tnadetnik pointed out on comments on the question, when a DLL needs another DLL, it's not safe to include the header file of the DLL to be used if therein the class is declared with AFX_EXT_CLASS. In this case, as the client code is also a DLL, AFX_EXT_CLASS would be defined as __declspec(dllexport) and not as __declspec(dllimport) as it should.