如何解决C++项目中的LNK2001问题

huangapple go评论62阅读模式
英文:

How to resolve LNK2001 in c++ projects

问题

I have two projects, the first one is a dynamic library project, lets say Log project, and there is a file: Log.h

#pragma once
#include "Core.h"
#include "spdlog/spdlog.h"

#include <memory>

namespace Prunus {
    class __declspec(dllexport) Log {
    public:
        static void Init();

        inline static std::shared_ptr<spdlog::logger>& GetCoreLogger() { return s_CoreLogger; }
        inline static std::shared_ptr<spdlog::logger>& GetClientLogger() { return s_ClientLogger; }
        static std::shared_ptr<spdlog::logger> s_CoreLogger;
        static std::shared_ptr<spdlog::logger> s_ClientLogger;
    };
}

while in Log.cpp, it is:

#include "Log.h"
#include "spdlog/sinks/stdout_color_sinks.h"

namespace Prunus {
    std::shared_ptr<spdlog::logger> Log::s_CoreLogger;
    std::shared_ptr<spdlog::logger> Log::s_ClientLogger;

    void Log::Init() {
        spdlog::set_pattern("%^[%T] %n: %v%$");
        s_CoreLogger = spdlog::stdout_color_mt("PRUNUS");
        s_CoreLogger->set_level(spdlog::level::trace);
        s_ClientLogger = spdlog::stdout_color_mt("APP");
        s_ClientLogger->set_level(spdlog::level::trace);
    }
}

And I tried to invoke the Log::Init() in Log project itself, it can work. But when I reference it in another project which references the Log project, it throws an error like:

Severity	Code	Description	Project	File	Line	Suppression State
Error	LNK2001	unresolved external symbol "public: static class std::shared_ptr<class spdlog::logger> Prunus::Log::s_CoreLogger" (?s_CoreLogger@Log@Prunus@@2V?$shared_ptr@Vlogger@spdlog@@@std@@A)	Sandbox	F:\code\Prunus\Prunus\Sandbox\SandboxApplication.obj	1

Not sure whether there are additional settings I missed in Visual Studio 2022.

I tried to use the Log::Init() inside the Log project, it can work, but it cannot while referencing it outside the project. What I want is to reference it outside the Log project.

英文:

I have two projects, the first one is a dynamic library project, lets say Log project, and there is a file:
Log.h

#pragma once
#include &quot;Core.h&quot;
#include &quot;spdlog/spdlog.h&quot;

#include &lt;memory&gt;

namespace Prunus{
	class __declspec(dllexport) Log
	{
	public:
		static void Init();

		inline static std::shared_ptr&lt;spdlog::logger&gt;&amp; GetCoreLogger() { return s_CoreLogger; }
		inline static std::shared_ptr&lt;spdlog::logger&gt;&amp; GetClientLogger() { return s_ClientLogger; }
		static std::shared_ptr&lt;spdlog::logger&gt; s_CoreLogger;
		static std::shared_ptr&lt;spdlog::logger&gt; s_ClientLogger;
	};
}

while in Log.cpp, it is:

#include &quot;Log.h&quot;
#include &quot;spdlog/sinks/stdout_color_sinks.h&quot;

namespace Prunus {
	std::shared_ptr&lt;spdlog::logger&gt; Log::s_CoreLogger;
	std::shared_ptr&lt;spdlog::logger&gt; Log::s_ClientLogger;

	void Log::Init() {
		spdlog::set_pattern(&quot;%^[%T] %n: %v%$&quot;);
		s_CoreLogger = spdlog::stdout_color_mt(&quot;PRUNUS&quot;);
		s_CoreLogger-&gt;set_level(spdlog::level::trace);
		s_ClientLogger = spdlog::stdout_color_mt(&quot;APP&quot;);
		s_ClientLogger-&gt;set_level(spdlog::level::trace);
	}
}

And I tried to invoke the Log::Init() in Log project it self, it can work.
But when I reference it in another project which references on Log project, it throws error like:

Severity	Code	Description	Project	File	Line	Suppression State
Error	LNK2001	unresolved external symbol &quot;public: static class std::shared_ptr&lt;class spdlog::logger&gt; Prunus::Log::s_CoreLogger&quot; (?s_CoreLogger@Log@Prunus@@2V?$shared_ptr@Vlogger@spdlog@@@std@@A)	Sandbox	F:\code\Prunus\Prunus\Sandbox\SandboxApplication.obj	1	

Not sure whether there are additional settings I missed in visual studio 2022

I tried to use the Log::Init() inside the Log project, it can work, but it can not while referencing outside the project. What I want is to reference it outside the Log project.

答案1

得分: 0

不要导出整个类,特别是如果它包含静态变量。

将函数声明与定义分开。

namespace Prunus {
    class Log
    {
    public:
        __declspec(dllexport) static void Init();
        __declspec(dllexport) inline static std::shared_ptr<spdlog::logger>& GetCoreLogger();
        __declspec(dllexport) inline static std::shared_ptr<spdlog::logger>& GetClientLogger();

    private:
        static std::shared_ptr<spdlog::logger> s_CoreLogger;
        static std::shared_ptr<spdlog::logger> s_ClientLogger;
    };
}

.cpp

namespace Prunus {
    std::shared_ptr<spdlog::logger> Log::s_CoreLogger;
    std::shared_ptr<spdlog::logger> Log::s_ClientLogger;

    void Log::Init() {
        // ...
        // ...
    }

    inline std::shared_ptr<spdlog::logger>& Log::GetCoreLogger() { return Log::s_CoreLogger; }
    inline std::shared_ptr<spdlog::logger>& Log::GetClientLogger() { return Log::s_CoreLogger; }
}
英文:

Do not export an entire class, especially if it contains static variables.

Separate function declaration from definition.

namespace Prunus {
    class   Log
    {
    public:
        __declspec(dllexport) static void Init();
        __declspec(dllexport)   inline static std::shared_ptr&lt;spdlog::logger&gt;&amp; GetCoreLogger();
        __declspec(dllexport)   inline static std::shared_ptr&lt;spdlog::logger&gt;&amp; GetClientLogger();

    private:
        static std::shared_ptr&lt;spdlog::logger&gt; s_CoreLogger;
        static std::shared_ptr&lt;spdlog::logger&gt; s_ClientLogger;
    };
}

.cpp

namespace Prunus {
    std::shared_ptr&lt;spdlog::logger&gt; Log::s_CoreLogger;
    std::shared_ptr&lt;spdlog::logger&gt; Log::s_ClientLogger;

    
        void Log::Init() {
          
           ...
           ...
        }

        inline   std::shared_ptr&lt;spdlog::logger&gt;&amp; Log::GetCoreLogger() { return Log::s_CoreLogger; }
        inline   std::shared_ptr&lt;spdlog::logger&gt;&amp; Log::GetClientLogger() { return Log::s_CoreLogger; }
   
}

huangapple
  • 本文由 发表于 2023年3月21日 00:25:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75792868.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定