由于asio2没有写技术文档,因此打算写几篇文章介绍一下如何使用它,主要是针对新手。
解压github下载的asio2压缩包之后,里面有3rd,include,test,example等文件夹,其中3rd文件夹包含了asio,cereal,fmt等一些开源库,asio2的代码需要用到这些开源库;include文件夹里面又包含了一个asio2文件夹,这个asio2文件夹是真正的asio2的相关代码;test文件夹是性能测试和单元测试相关的代码;example文件夹是各种使用示例代码;
最新版本的asio2代码可以使用cmake直接生成vs的解决方案等,打开vs解决方案即可直接编译,不需要任何其它额外设置(至于cmake如何使用,不会的话自己网络搜索)。
如果你对vs项目的头文件路径包含不熟悉,你可以直接参考cmake生成的vs解决方案里的头文件路径包含是如何设置的。
通常,如果你建立了自己的项目的vs解决方案(而不是使用的asio2里的cmake生成的解决方案),那么你需要在你的vs头文件路径包含中添加以下两项(假定你在github下载的是master分支的压缩包):asio2-master/3rd和asio2-master/include
如果你对项目头文件路径包含很熟悉,比如你有你自己的第三方库目录(比如你习惯把你自己用到的第三方库都放在这个目录下),那么你只需要把asio2-master/3rd里面的全部文件(是asio2-master/3rd里面的文件而不是asio2-master/3rd这个目录本身),和asio2-master/include里面的全部文件,放到你自己的第三方库目录即可。
比如像下面这样在dllmain.cpp中直接声明了一个asio2全局对象:
asio2::tcp_client client;
这就会导致在DLL的入口函数DllMain中出现死锁,死锁的原因是std::thread引起的,参考asio2/util/thread_pool.hpp开头的说明
需要用下面的方式,即声明一个指针,然后自己在DLL中做一个导出函数如Init(),在EXE中手动调用你的DLL中的导出函数Init(); 然后在Init()中创建指针。如:
// 在dllmain.cpp先声明一个全局的指针对象
std::shared_ptr<asio2::tcp_client> client;
// 这是你dll中的导出函数Init
void Init()
{
client = std::make_shared<asio2::tcp_client>();
}
// 然后在你的EXE中手动调用这个Init导出函数即可。
原因是由于在DLL_PROCESS_DETACH时,通过PostQueuedCompletionStatus投递的IOCP事件永远得不到执行。
解决办法依然是自己在DLL中做一个导出函数如Uninit(),在EXE中手动调用你的DLL中的导出函数Uninit();在Uninit函数中调用对象的stop函数;如:
// 这是你dll中的导出函数Uninit
void Uninit()
{
client->stop();
}
github : https://github.com/zhllxt/asio2 码云 : https://gitee.com/zhllxt/asio2
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。