C++ 模板类的Windows DLL链接器错误 模板 类核心API事件 { 公众: typedef typename std::函数EventHandler; 事件和运算符+=(常量EventHandler和toSubscribe) { 认购; 归还*这个; } void运算符() { 调用(发送方、参数…); } 无效订阅(const EventHandler和toSubscribe) { std::lock_guard locker(m_callbackMutex); m_回调。推回(toSubscribe); } 无效清除() { std::lock_guard locker(m_callbackMutex); m_回调。清除(); } void Invoke(const SenderType__*sender,Args__…Args)const { std::lock_guard locker(m_callbackMutex); for(自动iter=m_回调。开始();iter!=m_回调。结束();++iter) { (*iter)(发送方,args…); } } 私人: std::向量m_回调; 可变std::mutex m_callbackMutex; }; 模板类核心API事件;
在DLL的使用者中C++ 模板类的Windows DLL链接器错误 模板 类核心API事件 { 公众: typedef typename std::函数EventHandler; 事件和运算符+=(常量EventHandler和toSubscribe) { 认购; 归还*这个; } void运算符() { 调用(发送方、参数…); } 无效订阅(const EventHandler和toSubscribe) { std::lock_guard locker(m_callbackMutex); m_回调。推回(toSubscribe); } 无效清除() { std::lock_guard locker(m_callbackMutex); m_回调。清除(); } void Invoke(const SenderType__*sender,Args__…Args)const { std::lock_guard locker(m_callbackMutex); for(自动iter=m_回调。开始();iter!=m_回调。结束();++iter) { (*iter)(发送方,args…); } } 私人: std::向量m_回调; 可变std::mutex m_callbackMutex; }; 模板类核心API事件;,c++,windows,dll,C++,Windows,Dll,在DLL的使用者中 template <typename SenderType__, typename... Args__> class CORE_API Event { public: typedef typename std::function<void(const SenderType__*, Args__ ...)> EventHandler; Event& operator+=(const EventHandler& toSubsc
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>;
TEST(EventTest、testeventfires和passesargs)
{
事件;
事件+=&TestFunction;
事件+=&TestFunction2;
std::string sender=“TestEventFiresAndPassesArgs”;
std::string arg=“boo!”;
调用(&发送方,arg);
ASSERT_EQ(发送方、TestEventFires和PasseArgsSenderName);
ASSERT_EQ(arg、testeventfires和passesargstestarg);
ASSERT_EQ(发送器+函数2),TestEventFire和PasseArgsSenderName2);
ASSERT_EQ(arg+“Function2”,testEventFire和passeSargstestarg2);
}
那么链接器输出是:
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:错误LNK2019:未解析的外部符号“\uu declspec(dllimport)public:class CompanyName::Utils::Event&\uu cdecl CompanyName::Utils::Event::operator+=(class std::function const&)”(“小鬼”$Event@V?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@V12@@Utils@CompanyName@@QEAAAEAV012@AEBV?$function@$$A6AXPEBV?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@V12@@Z@std@@@Z) 在函数“private:virtual void\uu cdecl EventTest\u testeventfires和passesargs\u Test::TestBody(void)”中引用(?TestBody@EventTest_TestEventFiresAndPassesArgs_Test@@EEAAXXZ)
2> EventTest.obj:错误LNK2019:未解析的外部符号“\uu declspec(dllimport)public:void\uu cdecl CompanyName::Utils::Event::Invoke(class std::basic_string const*,class std::basic_string)const”(uu imp?Invoke@$Event@V?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@V12@@Utils@CompanyName@@QEBAXPEBV?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@V45@@Z)在函数“private:virtual void\u cdecl EventTest\u testeventfires和passesargs\u Test::TestBody(void)”中引用(?TestBody@EventTest_TestEventFiresAndPassesArgs_Test@@EEAAXXZ)
2> EventTest.obj:错误LNK2019:未解析的外部符号“\uu declspec(dllimport)public:\uuu cdecl CompanyName::Utils::Event::Event(void)”(\uu imp\u0$Event@V?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@V12@@Utils@CompanyName@@QEAA@XZ)在函数中引用“private:virtual void\uuu cdecl EventTest\u TestEventFiresAndPassesArgs\u Test::TestBody(void)”(?TestBody@EventTest_TestEventFiresAndPassesArgs_Test@@EEAAXXZ)
2> EventTest.obj:错误LNK2019:未解析的外部符号“\uuu declspec(dllimport)public:\uuuu cdecl CompanyName::Utils::Event::~Event(void)”(\uuu imp\u1$Event@V?$basic_string@DU?$char_traits@D@性病病毒$allocator@D@2@@std@@V12@@Utils@CompanyName@@QEAA@XZ)在函数中引用”私有:虚拟void u cdecl EventTest TestEventFiresAndPassesArgs Test::TestBody(void)”(?TestBody@EventTest_TestEventFiresAndPassesArgs_Test@@EEAAXXZ)
2> ..\runCoreUnitTests.exe:致命错误LNK1120:4个未解析的外部
你知道我做错了什么吗?在创建DLL时,需要使用
\uu declspec(dllexport)
导出函数
通过使用\uu declspec(dllimport)
声明这些函数,可以从另一个DLL使用这些函数
这些功能非常适合常规功能
但是,对于类模板和函数模板,模板是根据需要实例化的。它们不会导出到定义它们的DLL中。因此,它们也不能从DLL中导入。因此,您不使用
\u declspec(dllexport)
或\u declspec(dllimport)
带有类模板和函数模板。是头文件还是what@Alf它是一个头文件。这是一个编译成dll的库。然后消费者是我的单元测试可执行文件--它是一个cpp文件..嗯,那么CORE_API意味着什么?你不能从dll导出模板。35;如果定义了(_MSC_VER)#pragma警告(禁用:4251)#ifdef Core_EXPORTS#define Core_API(dllexport)#else#define Core_API(dllimport)#endif/*Core_EXPORTS/#else/defined(_WIN32)*/#定义核心API#endif@Cheers还有hth.-Alf如果我不能导出模板,那么它们几乎一文不值,MSFT编译器也会浪费大量时间。这似乎向我表明,你不能使用DLL定义的模板。当你在DLL中定义模板时,只有在有人尝试实例化temp时,类/函数才会真正得到定义模板就像蓝图。它们是用来构建具体的类和函数的。有一个显式的实例化(第一个代码块的最后一行)正在导出。这应该是可能的,尽管我自己从未尝试过/cc@JonathanHensonThanks,以获得有关从动态库导出/导入类/函数模板的精彩而简单的解释!我在编译dll时遇到问题。我从dll导出所有类和类模板时出错(我试图编译linux dll,并通过查找和替换向所有类添加了简单的导出宏)。我有很多与问题无关的错误。然后,我在这里找到了你的帖子,删除了所有带有类模板的导出宏,错误消失了:)
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