首页 > 解决方案 > 在另一个 VS 项目中引用函数模板的显式实例时出现 LNK2019 错误

问题描述

在尝试将具有显式实例化函数模板的类引用到另一个 Visual Studio 2013 项目时,我遇到了 LNK2019 链接器错误。

显式实例化在同一个项目 (project1) 中工作。但是,一旦我尝试从另一个项目(project2)引用 project1 中的函数模板,我就会得到 LNK2019 错误链接器。

我在两个项目中都使用了 __cdecl 调用约定(/Gd 标志)。

项目一:

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

我得到的错误是:

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

标签: c++templatesvisual-c++dllexplicit-instantiation

解决方案


正如 IgorTandetnik 指出的那样,我必须将 FOO_API (__declspec(dllexport)) 添加到显式模板实例化中。正如他还指出的那样,没有必要将其保留在声明中,因此我将其删除。

所以,在 Project1/foo.c 中,我改变了

template void foo::someFunc(int a, int b); 
template void foo::someFunc(int a, short b);

至:

template FOO_API void foo::someFunc(int a, int b);
template FOO_API void foo::someFunc(int a, short b);

在 Project1/foo.h 中,我改变了

FOO_API void someFunc(U a, T b);

void someFunc(U a, T b);

推荐阅读