James
James

Reputation: 300

LNK2019 error when referring an explicit instantiation of a function template in another VS project

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.

Project 1:

//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
}

Project 2:

//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

Answers (1)

James
James

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

Related Questions