gpt4 book ai didi

c++ - 模板类的 Windows DLL 链接器错误

转载 作者:可可西里 更新时间:2023-11-01 10:05:39 26 4
gpt4 key购买 nike

template <typename SenderType__, typename... Args__>
class CORE_API Event
{
public:
typedef typename std::function<void(const SenderType__*, Args__ ...)> EventHandler;

Event& operator+=(const EventHandler& toSubscribe)
{
Subscribe(toSubscribe);
return *this;
}

void operator()(const SenderType__* sender, Args__ ... args) const
{
Invoke(sender, args...);
}

void Subscribe(const EventHandler& toSubscribe)
{
std::lock_guard<std::mutex> locker(m_callbackMutex);
m_callbacks.push_back(toSubscribe);
}

void Clear()
{
std::lock_guard<std::mutex> locker(m_callbackMutex);
m_callbacks.clear();
}

void Invoke(const SenderType__* sender, Args__ ... args) const
{
std::lock_guard<std::mutex> locker(m_callbackMutex);
for (auto iter = m_callbacks.begin(); iter != m_callbacks.end(); ++iter)
{
(*iter)(sender, args...);
}
}

private:
std::vector<EventHandler> m_callbacks;
mutable std::mutex m_callbackMutex;
};

template class CORE_API Event<std::string, std::string>;

在 DLL 的消费者中......

TEST(EventTest, TestEventFiresAndPassesArgs)
{
Event<std::string, std::string> event;
event += &TestFunction;
event += &TestFunction2;
std::string sender = "TestEventFiresAndPassesArgs";
std::string arg = "boo!";
event.Invoke(&sender, arg);
ASSERT_EQ(sender, testEventFiresAndPassesArgsSenderName);
ASSERT_EQ(arg, testEventFiresAndPassesArgsTestArg);
ASSERT_EQ(sender + "Function2", testEventFiresAndPassesArgsSenderName2);
ASSERT_EQ(arg + "Function2", testEventFiresAndPassesArgsTestArg2);
}

那么链接器的输出是:

EventTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class CompanyName::Utils::Event<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > & __cdecl CompanyName::Utils::Event<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::operator+=(class std::function<void __cdecl(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)> const &)" (__imp_??Y?$Event@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Utils@CompanyName@@QEAAAEAV012@AEBV?$function@$$A6AXPEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Z@std@@@Z) referenced in function "private: virtual void __cdecl EventTest_TestEventFiresAndPassesArgs_Test::TestBody(void)" (?TestBody@EventTest_TestEventFiresAndPassesArgs_Test@@EEAAXXZ)
2>EventTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __cdecl CompanyName::Utils::Event<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::Invoke(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)const " (__imp_?Invoke@?$Event@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Utils@CompanyName@@QEBAXPEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V45@@Z) referenced in function "private: virtual void __cdecl EventTest_TestEventFiresAndPassesArgs_Test::TestBody(void)" (?TestBody@EventTest_TestEventFiresAndPassesArgs_Test@@EEAAXXZ)
2>EventTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl CompanyName::Utils::Event<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::Event<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (__imp_??0?$Event@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Utils@CompanyName@@QEAA@XZ) referenced in function "private: virtual void __cdecl EventTest_TestEventFiresAndPassesArgs_Test::TestBody(void)" (?TestBody@EventTest_TestEventFiresAndPassesArgs_Test@@EEAAXXZ)
2>EventTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl CompanyName::Utils::Event<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::~Event<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (__imp_??1?$Event@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Utils@CompanyName@@QEAA@XZ) referenced in function "private: virtual void __cdecl EventTest_TestEventFiresAndPassesArgs_Test::TestBody(void)" (?TestBody@EventTest_TestEventFiresAndPassesArgs_Test@@EEAAXXZ)
2>..\runCoreUnitTests.exe : fatal error LNK1120: 4 unresolved externals

知道我在这里做错了什么吗?

最佳答案

创建 DLL 时需要使用 __declspec(dllexport) 导出函数。

您可以通过使用 __declspec(dllimport) 声明这些函数来使用其他 DLL 中的此类函数。

这些非常适合常规功能。

但是,对于类模板和函数模板,模板是根据需要实例化的。它们不会导出到定义它们的 DLL。因此,它们也无法从 DLL 中导入。因此,您不要将 __declspec(dllexport)__declspec(dllimport) 与类模板和函数模板一起使用。

关于c++ - 模板类的 Windows DLL 链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28181020/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com