error ​​LNK2001​​: unresolved external symbol, 后面会有LNK1120 unresolved externals错误

1.缺少依赖的.lib, .obj文件
1.一个dll调用另外dll的函数时,被调用的函数不存在,
2. 调用dll中的函数调用传参不一致,定义函数的dll中声明与定义的函数接口参数类型不同
3. 只在类中声明了静态属性,没有定义,需要在外面对类的静态属性进行定义
4. 如果使用的内联函数是在.cpp文件内定义的,而不是在头文件.h内定义将导致LNK2001错误
5. 从基类的构造函数或析构函数中调用虚拟函数时将会导致LNK2001
6. 试图在C++的  多个文件内使用全局变量也会产生LNK2001错误。
  ** 需要时在头文件中加入该常量的初始化代码,并在.CPP文件中包含该头文件
  ** 使用时给该变量赋以常数。
7. Tools > Options > Projects > VC++ Directories, Library files更新路径

Singleton.h

#pragma once
#include <mutex>

class Singleton
{
private:
// 静态属性只是声明,没有定义
static Singleton* ptrInstance;
static std::mutex m_mutex;

Singleton() {
ptrInstance = NULL;
}

public:
static Singleton* getInstance();
~Singleton();
};

 lib_link_input_1.cpp

// lib_link_input_1.cpp
// compile by using: cl /LD lib_link_input_1.cpp
__declspec(dllexport) int Test() {
return 213;
}

Singleton.cpp

// Singleton.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include "Singleton.h"

Singleton* Singleton::getInstance()
{
if (Singleton::ptrInstance == NULL)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (ptrInstance == NULL)
{
ptrInstance = new Singleton();
}
}
return ptrInstance;
}

Singleton::~Singleton()
{
if (ptrInstance != NULL)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (ptrInstance != NULL)
{
delete ptrInstance;
}
}
}

// error LNK2001: unresolved external symbol "private: static class std::mutex Singleton::m_mutex" (?m_mutex@Singleton@@0Vmutex@std@@A)
std::mutex Singleton::m_mutex;
// error LNK2001: unresolved external symbol "private: static class Singleton * Singleton::ptrInstance" (?ptrInstance@Singleton@@0PEAV1@EA)
Singleton* Singleton::ptrInstance = NULL;

__declspec(dllimport) int Test();

int main()
{
std::cout << Test() << std::endl;

Singleton* obj1 = Singleton::getInstance();
Singleton* obj2 = Singleton::getInstance();

if (obj1 == NULL) {
std::cout << "obj1 is null" << std::endl;
}

if (obj2 == NULL) {
std::cout << "obj2 is null" << std::endl;
}

if (obj1 == obj2) {
std::cout << "Single obj1 equals obj2" << std::endl;
}
else {
std::cout << "Single obj1 != obj2" << std::endl;
}
system("pause");
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件