Reputation: 300
I'm experiencing a LNK2019 linker error when trying to reference a class with a explicitly instantiated function template into another Visual Studio 2013 project.
The explicit instantiations works inside the same project (project1). But as soon as I try to reference the function template in project1 from another project (project2), I get the LNK2019 error linker.
I am using the __cdecl calling convention (/Gd flag) in both projects.
//foo.h:
#define FOO_API __declspec(dllexport)
class FOO_API foo
{
public:
//basic constructor and destructor declartions
template <class U, class T>
FOO_API void someFunc(U a, T b);
};
//foo.c:
#include "foo.h"
//basic constructor and destructor definitions
template<class U, class T>
void foo::someFunc(U a, T b)
{
// do something
}
template void foo::someFunc(int a, int b);
template void foo::someFunc(int a, short b);
//bar1.h:
class bar1
{
public:
//basic constructor and destructor declarations
void someOtherFunc();
};
//bar1.cpp:
#include "bar1.h"
#include "foo.h"
void bar1::someOtherFunc()
{
int a = 1, b = 2;
short c = 3;
char d = 'd';
foo * myFoo = new foo();
myFoo->someFunc(a, b); // Works as expected, as <int, int> was explicity instantiated in foo.cpp
myFoo->someFunc(a, c); // Works as expected, as <int, int> was explicity instantiated in foo.cpp
//myFoo->someFunc(a, d); // Fails as expected, no explicit <int, char> instantiation in foo.cpp
}
//bar2.h
class bar2
{
public:
//basic constructor and destructor declarations
void someOtherFunc();
};
//bar2.cpp:
#include "bar2.h"
#include "..\project1\foo.h"
//basic constructor and destructor definitions
void bar2::someOtherFunc()
{
int a = 1, b = 2;
short c = 3;
char d = 'd';
foo * myFoo = new foo();
myFoo->someFunc(a, b); // Doesn't work
myFoo->someFunc(a, c); // Doesn't work
}
The error I get is:
1>------ Build started: Project: Project2, Configuration: Debug x64 ------
1>bar2.obj : error LNK2019: unresolved external symbol "public: void __cdecl foo::someFunc<int,int>(int,int)" (??$someFunc@HH@foo@@QEAAXHH@Z) referenced in function "public: void __cdecl bar2::someOtherFunc(void)" (?someOtherFunc@bar2@@QEAAXXZ)
1>bar2.obj : error LNK2019: unresolved external symbol "public: void __cdecl foo::someFunc<int,short>(int,short)" (??$someFunc@HF@foo@@QEAAXHF@Z) referenced in function "public: void __cdecl bar2::someOtherFunc(void)" (?someOtherFunc@bar2@@QEAAXXZ)
1>c:\Projects\ExplicitTemplateTest\x64\Debug\Project2.dll : fatal error LNK1120: 2 unresolved externals
Upvotes: 2
Views: 611
Reputation: 300
As IgorTandetnik pointed out, I had to add the FOO_API
(__declspec(dllexport)
) to the explicit template instantiations. As he also pointed out, there was no need to keep it on the declaration, so I removed it.
So, inside Project1/foo.c, I changed
template void foo::someFunc(int a, int b);
template void foo::someFunc(int a, short b);
to:
template FOO_API void foo::someFunc(int a, int b);
template FOO_API void foo::someFunc(int a, short b);
and inside Project1/foo.h, I changed
FOO_API void someFunc(U a, T b);
to
void someFunc(U a, T b);
Upvotes: 2