behaviac动态库运行出错

behaviac动态库运行出错

(金庆的专栏 2017.3.16)

游戏是静态链接的运行库,添加behaviac动态库后,运行出错:

>    ucrtbased.dll!free_dbg_nolock(void * const block, const int block_use) 行 996    C++
     ucrtbased.dll!_free_dbg(void * block, int block_use) 行 1030    C++
     libbehaviac_msvc_debug.dll!operator delete(void * block) 行 17    C++
     libbehaviac_msvc_debug.dll!std::_Deallocate(void * _Ptr, unsigned int _Count, unsigned int _Sz) 行 132    C++
     libbehaviac_msvc_debug.dll!std::allocator::deallocate(std::_Container_proxy * _Ptr, unsigned int _Count) 行 720    C++
     libbehaviac_msvc_debug.dll!std::_Wrap_alloc >::deallocate(std::_Container_proxy * _Ptr, unsigned int _Count) 行 988    C++
     libbehaviac_msvc_debug.dll!std::_String_alloc > >::_Free_proxy() 行 661    C++
     libbehaviac_msvc_debug.dll!std::_String_alloc > >::~_String_alloc > >() 行 629    C++
     libbehaviac_msvc_debug.dll!std::basic_string,std::allocator >::~basic_string,std::allocator >() 行 1018    C++
     libbehaviac_msvc_debug.dll!behaviac::CTagObject::Save(behaviac::IIONode * node, const char * szClassName) 行 100    C++
     libbehaviac_msvc_debug.dll!behaviac::Agent::InitVariableRegistry() 行 476    C++
     libbehaviac_msvc_debug.dll!behaviac::Agent::Init_(int contextId, behaviac::Agent * pAgent, short priority, const char * agentInstanceName) 行 227    C++
     giant_test_client.exe!behaviac::Agent::InitAgent(behaviac::Agent * pAgent, const char * agentInstanceName, const char * agentInstanceNameAny, bool bToBind, int contextId, short priority) 行 56    C++
     giant_test_client.exe!behaviac::Agent::Create(const char * agentInstanceName, int contextId, short priority) 行 88    C++
     giant_test_client.exe!Client::InitPlayer() 行 36    C++
     giant_test_client.exe!Client::Client() 行 23    C++
     giant_test_client.exe!main() 行 50    C++
     giant_test_client.exe!invoke_main() 行 64    C++
     giant_test_client.exe!__scrt_common_main_seh() 行 253    C++
     giant_test_client.exe!__scrt_common_main() 行 296    C++
     giant_test_client.exe!mainCRTStartup() 行 17    C++
     kernel32.dll!@BaseThreadInitThunk@12()    未知
     ntdll.dll!___RtlUserThreadStart@8()    未知
     ntdll.dll!__RtlUserThreadStart@8()    未知

看来是string跨越动态库析构。
如果string在动态库中构造又析构,动态库的运行时库可以与主程序不同。
但如果用主程序的运行时申请内存,在动态库中用另一个运行时库释放,就会产生上面的错误。

可以建立一个最小化的程序来复现上面的错误。
新建一个行为树,为Agent创建一个属性。
然后主程序运行库设为:多线程调试 (/MTd),而不是:多线程调试 DLL (/MDd)。
调试运行创建Agent时就会出上面错误。

疑问是这是动态库内部调用,怎么会产生跨库析构呢?

断点进入string的构造过程可以发现,string不是动态库构造的,而是主程序构造的:

>    test_client.exe!behaviac::StringUtils::internal::ToString(const std::basic_string,std::allocator > & val) 行 138    C++
     test_client.exe!behaviac::StringUtils::Detail::ToStringPtrHanler,std::allocator >,0>::ToString(const std::basic_string,std::allocator > & v) 行 192    C++
     test_client.exe!behaviac::StringUtils::Detail::ToStringEnumHanler,std::allocator >,0>::ToString(const std::basic_string,std::allocator > & v) 行 228    C++
     test_client.exe!behaviac::StringUtils::Detail::ToStringStructHanler,std::allocator >,0>::ToString(const std::basic_string,std::allocator > & val) 行 242    C++
     test_client.exe!behaviac::StringUtils::ToString,std::allocator > >(const std::basic_string,std::allocator > & val) 行 256    C++
     test_client.exe!behaviac::SetFromString_t,std::allocator >,0>::Get(std::basic_string,std::allocator > & value) 行 790    C++
     test_client.exe!behaviac::CProperty,std::allocator > >::GetValueToString(const behaviac::Agent * self) 行 848    C++
     libbehaviac_msvc_debug.dll!behaviac::CTagObject::Save(behaviac::IIONode * node, const char * szClassName) 行 97    C++
     libbehaviac_msvc_debug.dll!behaviac::Agent::InitVariableRegistry() 行 476    C++
     libbehaviac_msvc_debug.dll!behaviac::Agent::Init_(int contextId, behaviac::Agent * pAgent, short priority, const char * agentInstanceName) 行 227    C++
     test_client.exe!behaviac::Agent::InitAgent(behaviac::Agent * pAgent, const char * agentInstanceName, const char * agentInstanceNameAny, bool bToBind, int contextId, short priority) 行 56    C++
     test_client.exe!behaviac::Agent::Create(const char * agentInstanceName, int contextId, short priority) 行 88    C++
     test_client.exe!Client::InitPlayer() 行 36    C++
     test_client.exe!Client::Client() 行 23    C++
     test_client.exe!main() 行 50    C++
     test_client.exe!invoke_main() 行 64    C++
     test_client.exe!__scrt_common_main_seh() 行 253    C++
     test_client.exe!__scrt_common_main() 行 296    C++
     test_client.exe!mainCRTStartup() 行 17    C++
     kernel32.dll!75c3336a()    未知
     [下面的框架可能不正确和/或缺失,没有为 kernel32.dll 加载符号]    
     ntdll.dll!76fa9902()    未知
     ntdll.dll!76fa98d5()    未知

原因为 IProperty::GetValueToString()是虚函数,实际实现是由主程序实现模板类。
    behaviac::CProperty<>::GetValueToString()

解决方案为使用behaviac静态库并且静态链接运行时库。



本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部