"unresolved external symbol" error when accessing a static member of a template class inside a DLL

  • Thread starter Thread starter zzzhhhzzzhhh
  • Start date Start date
Z

zzzhhhzzzhhh

Guest
Environment:

- Windows 10 version 1803

- Visual Studio 2015 Update 3

- Debug x64 configuration in VS

I encountered "unresolved external symbol" error when accessing a static member of a template class inside a DLL. The source below is minimized so it may look senseless, but it helps focus on the problem.

Source:

There are two projects in the solution:

1) DllProject, built as a dll, contains three sources: Dll.h, Dll2.h and Dll2.cpp.

Dll.h:

#pragma once
#include "Dll2.h"

#ifdef _WINDLL
#define API_TYPE __declspec(dllexport)
#else
#define API_TYPE __declspec(dllimport)
#endif

class API_TYPE AClass {
public:
template <class T> void Wrapper() {
BClass<T>::testStatic();
}
};




Dll2.h:

#pragma once

template <typename T>
class BClass {
public:
static T m_Static;
static T testStatic();
};

template <typename T>
T BClass<T>::testStatic() {
//do something to m_Static
return m_Static;
}


Dll2.cpp:

#include "Dll2.h"

template <typename T>
T BClass<T>::m_Static; //instantiate the static variable

template class BClass<float>; //instantiate the template class


2) ExeProject, built as an exe, contains Exe.cpp.

Exe.cpp:

#include "Dll.h"

int main() {
AClass a;
a.Wrapper<float>();
}

The idea behind the solution structure is as follows. The exe program ExeProject calls functions in dll, with Dll.h specifying the interface. To abstract complexities as many large opensources do, Dll.h only provides a wrapper of the underlying details, and it is this wrapper that is called by exe. The details are implemented by a template class -- BClass -- in Dll2.h and Dll2.cpp. BClass is used only inside the dll so it is not qualified with __declspec(dllexport). Since it is a template class, I explicitly instantiate it in Dll2.cpp at line 6. The problem is caused by the static member in BClass. Since it is static, I need to instantiate it and this is done in line 3-4 in Dll2.cpp, so there is an m_Static static variable inside dll that the dll uses through static function testStatic(). The DllProject compiles correctly. The exe project ExeProject also compiles without any problem. But errors arise at linking time:

1>------ Build started: Project: ExeProject, Configuration: Debug x64 ------
1>Exe.obj : error LNK2001: unresolved external symbol "public: static float BClass<float>::m_Static" (?m_Static@?$BClass@M@@2MA)
1>C:\tmp\DllProject\x64\Debug\ExeProject.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

I don't have much latitude to try. BClass is not supposed to be open to exe so I'm not going to add __declspec(dllexport) to it. Also I would like to keep the implementation of static function testStatic() in the Dll2.h header due to the application requirement (Actually a similar error will arise if I move it to Dll2.c -- the function itself would become the "unresolved external symbol". But I'm not going to discuss it in this thread). I have instantiated both the template BClass class and the static variable, so it should be linked without any problem. I'm really at my wit's end. I hope you could help me find out why I encounter the above error and how to fix it (while keeping the main code structure unchanged). Thank you.

















The as that the problem can be spot more accurately.

Continue reading...
 
Back
Top