【vcpkg】cpprestsdk之64位编译链接及踩坑
▒ 目录 ▒
- 🛫 问题
- 描述
- 1️⃣ 多版本vs报错
- 指定VS路径
- 2️⃣ error LNK2001: 问题排查
- 通过IDA打开lib文件,确认导出内容
- 查看源码
- 增加参数--editable,重新编译
- 3️⃣ error LNK2001: 外部符号`__imp_?close_...`
- 去除`__imp_`
- 🛬 结论
- vcpkg卸载重载
- 编译指定版本的源码(未验证)
- 修改源码进行编译
- 📖 参考资料
🛫 问题
描述
cpprestsdk之前编译过32位,已经踩了一些坑,本以为64位编译会顺风顺水,然而事与愿违,特此记录几个问题。
最终编译命令为vcpkg install cpprestsdk[websockets]:x64-windows-static --recurse --editable。
1️⃣ 多版本vs报错
目标编译为2019,但是由于重装系统后,直接安装了2022的vs,导致没有了2019的
x64 Native Tools Command Prompt for VS 2019环境,后又安装2019才解决问题。
指定VS路径
vs2019和2022共存的情况下,直接运行
install命令,将报下面错误。
这个错误信息,一开始看的挺头晕,后来认真看了错误提示,发现vcpkg找到的路径是2022,但是它也给出了文档连接https://github.com/microsoft/vcpkg/blob/master/docs/users/triplets.md#VCPKG_VISUAL_STUDIO_PATH,可以解决该问题。
小编以安装根目录
J:\_ALL\CODE\vcpkg\vcpkg\和x64-windows-static的编译目标为例,所以我们需要修改的文件是J:\_ALL\CODE\vcpkg\vcpkg\triplets\x64-windows-static.cmake。修改内容如下:
set(VCPKG_VISUAL_STUDIO_PATH "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community")
set(VCPKG_PLATFORM_TOOLSET v142)
2️⃣ error LNK2001: 问题排查
运行install命令,生成的lib进行集成的时候,提示未找到
__imp_?close_pending_tasks_with_error@websocket_client_task_impl@details@client@websockets@web@@QEAAXAEBVwebsocket_exception@345@@Z(web::websockets::client::details::websocket_client_task_impl::close_pending_tasks_with_error)的错误。
各种搜索,没找到解决方案,只能编译链接原理通过一步步排查了
通过IDA打开lib文件,确认导出内容
通过删选关键字
web::websockets::client::details::websocket_client_task_impl::,查看导出列表,的确没有导出函数close_pending_tasks_with_error。
查看源码
搜索源码,定位到源码文件
J:\_ALL\CODE\vcpkg\vcpkg\buildtrees\cpprestsdk\src\ecb9e168c5-96a8d6ba89.clean\Release\src\websockets\client\ws_client.cpp。
函数close_pending_tasks_with_error的编译条件是#if !defined(CPPREST_EXCLUDE_WEBSOCKETS),也就是说,当不定义CPPREST_EXCLUDE_WEBSOCKETS的时候就能将函数编译进去。
定位宏定义,最终在文件
J:\_ALL\CODE\vcpkg\vcpkg\buildtrees\cpprestsdk\src\ecb9e168c5-96a8d6ba89.clean\Release\include\cpprest\details\basic_types.h中找到下面代码。
#if defined(_WIN32)
// Include on everything except Windows Desktop ARM, unless explicitly excluded.
#if !defined(CPPREST_EXCLUDE_WEBSOCKETS)
#if defined(WINAPI_FAMILY)
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && defined(_M_ARM)
#define CPPREST_EXCLUDE_WEBSOCKETS
#endif
#else
#if defined(_M_ARM)
#define CPPREST_EXCLUDE_WEBSOCKETS
#endif
#endif
#endif
#endif
不必管这些定义,在代码最后直接取消宏定义
#undef CPPREST_EXCLUDE_WEBSOCKETS
增加参数–editable,重新编译
--editable的含义是不清空代码,直接编译,最终命令为:
vcpkg install cpprestsdk[websockets]:x64-windows-static --recurse --editable
再次通过IDA查看导出函数,可以看到lib中已经有函数close_pending_tasks_with_error了。
ps: 貌似参数
--no-downloads也是可以的。
3️⃣ error LNK2001: 外部符号__imp_?close_...
去除__imp_
通过上面的操作,命名已经将函数编译到lib中了,为啥还是报错呢?想来想去只能是编译的类型不一样,通过BCompare工具,比较两个函数名,可以看出,需要的函数带
__imp_。
查资料,发现:如果函数声明增加了__declspec(dllimport) ,链接的时候函数名会加上__imp_前缀,所以如果链接静态库, 函数的声明不用增加__declspec(dllimport) 。如果链接动态库,再增加__declspec(dllimport)。
定位到函数声明,可以看到声明为_ASYNCRTIMP void close_pending_tasks_with_error(const websocket_exception& exc);,查看_ASYNCRTIMP的定义:
所以在项目中,增加
_NO_ASYNCRTIMP即可。
也可以在引入cpprest头文件之前,定义_NO_ASYNCRTIMP宏,如下图所示:
🛬 结论
解决思路:
- 确认lib中包含目标函数
- 确保目标函数编译后的名字一模一样。
vcpkg卸载重载
开发过程中,经常要修改参数,重新编译库,已经安装的库无法重新安装,只能先卸载才能继续安装。
vcpkg remove cpprestsdk:x64-windows-static --recurse
编译指定版本的源码(未验证)
通过命令
.\vcpkg x-history cpprestsdk,查看cpprestsdk历史版本。
小编以安装根目录
J:\_ALL\CODE\vcpkg\vcpkg\为例,所以我们需要修改的文件是J:\_ALL\CODE\vcpkg\vcpkg\ports\cpprestsdk\vcpkg.json。修改内容如下:
也就是指定字段
version-semver。
参考资料:
- 随心所欲地对vcpkg依赖进行版本控制 https://zhuanlan.zhihu.com/p/352709760
- https://learn.microsoft.com/zh-cn/vcpkg/users/versioning
修改源码进行编译
vcpkg install每次默认都将代码删除,然后再下载解压代码,所以直接修改代码会被清除。
执行命令中,增加参数--editable,将不再删除代码。命令如下所示:
vcpkg install cpprestsdk[websockets]:x64-windows-static --recurse --editable。
📖 参考资料
- 【vcpkg】cpprestsdk编译链接及实战 Chrome Devtool Protocol https://blog.csdn.net/kinghzking/article/details/125772160
- vcpkg环境变量官方文档 https://github.com/microsoft/vcpkg/blob/master/docs/users/triplets.md#VCPKG_VISUAL_STUDIO_PATH
- VCPKG 环境变量 https://www.cnblogs.com/vcpkg/p/15019968.html
- vcpkg版本说明: https://learn.microsoft.com/zh-cn/vcpkg/users/versioning
相关文章:
【vcpkg】cpprestsdk之64位编译链接及踩坑
▒ 目录 ▒🛫 问题描述1️⃣ 多版本vs报错指定VS路径2️⃣ error LNK2001: 问题排查通过IDA打开lib文件,确认导出内容查看源码增加参数--editable,重新编译3️⃣ error LNK2001: 外部符号__imp_?close_...去除__imp_🛬 结论vcpkg…...
初始QML
Qt Quick的介绍 : Qt Quick是QML的标准类型和功能库。它包括视觉类型,交互类型,动画,模型和视图,粒子效果和着色器效果。QML 应用程序开发人员可以通过单个导入语句访问所有这些功能,简单来说Qt Quick是一…...
SpringAOP切面实例实现对数据过滤返回,SpringAOP切面实现对用户权限控制,通过@Around注解过滤修改方法返回值
文章目录需求内容:实现:步骤一:导入SpringAOP相关依赖pom.xml步骤二:自定义两个注解步骤三:需要用到的实体类**步骤四:切面具体实现**用法1.需要过滤返回值的方法添加注解FilterByUser2.数据Dto在需要过滤的字段添加Fi…...
【Kubernetes】【九】Label,Deployment,Service
Label Label是kubernetes系统中的一个重要概念。它的作用就是在资源上添加标识,用来对它们进行区分和选择。 Label的特点: 一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等等一个资源对象可以定义任意数量的L…...
RuoYi-Vue部署(Nginx+Tomcat)
环境搭建RuoYi-Vue搭建、Linux安装Nginx、Linux安装JDK8、Linux安装MySql8、Linux安装Redis、Linux安装Tomcat9前端打包 1.ruoyi-ui鼠标右键-->打开于终端2.安装依赖:npm install --registryhttps://registry.npm.taobao.org-->node_modules3.编译打包&#x…...
Hive提升篇-Hive修改事务
简介 Hive 默认是不允许数据更新操作的,毕竟它不擅长,即使在0.14版本后,做一些额外的配置便可开启Hive数据更新操作。而在海量数据场景下做update、delete之类的行级数据操作时,效率并不如意。 简单使用 修改HIVE_HOME/conf/hi…...
PMP项目管理未来的发展与趋势
什么是项目管理?关于项目管理的解释主要是基于国际项目管理三大体系不同的解释及本领域权威专家的解释。 项目管理就是以项目为对象的系统管理方法,通过一个临时性的、专门的柔性组织,对项目进行高效率的计划、组织、指导和控制,以…...
深度学习算法面试常问问题(三)
pooling层是如何进行反向传播的? average pooling: 在前向传播中,就是把一个patch的值取平均传递给下一层的一个像素。因此,在反向传播中,就是把某个像素的值平均分成n份 分配给上一层。 max pooling: 在前…...
GEE学习笔记 八十七:python版GEE动态加载地图方法
在Google Earth Engine的python版API更新后,之前使用folium动态加载地图的代码就不能在正常运行,因为整个Google Earth Engine的地图加载服务的URL发生了更新,所以我们也需要更新相关绘制方法。下面我会讲解一种新的绘制方法,大家…...
第三章 SQL错误信息
文章目录第三章 SQL错误信息SQLCODE 0和100SQLCODE -400检索SQL消息文本第三章 SQL错误信息 下表列出了SQL数字错误代码及其错误消息。这些代码作为SQLCODE变量值返回。 注意:虽然本文档将错误代码列为负值,但JDBC和ODBC客户端始终收到正值。例如&…...
axios中的resolvePromise为什么影响promise状态
axios的取消请求意思很简单,就是在发送请求后不久停止发送请求 本文探讨的是v0.22.0之前的CancelToken API,因为在阅读源码交流的时候发现很多朋友不理解为什么CancelToken中的resolvePromise会影响到实例对象身上的promise状态 即下图所示代码…...
AWS攻略——创建VPC
文章目录创建一个可以外网访问的VPCCIDR主路由表DestinationTarget主网络ACL入站规则出站规则子网创建EC2测试连接创建互联网网关(IGW)编辑路由表知识点参考资料在 《AWS攻略——VPC初识》一文中,我们在AWS默认的VPC下部署了一台可以SSH访问的…...
一文搞懂ECU休眠唤醒之利器-TJA1145
前言 首先,小T请教大家几个小小问题,你清楚: 什么是TJA1145吗?你知道休眠唤醒控制基本逻辑是怎么样的吗?TJA1145又是如何控制ECU进行休眠唤醒的呢?使用TJA1145时有哪些注意事项呢? 今天&…...
【Java基础】022 -- Lambda与递归练习
目录 一、Lambda表达式 1、Lambda初体验 2、函数式编程 3、Lambda表达式的标准格式 4、小结 5、Lambda表达式的省略写法 ①、示例代码 ②、小结 6、Lambda表达式的练习 ①、Lambda表达式简化Comparator接口的匿名形式 二、综合练习 1、按照要求进行排序(…...
技研智联云原生容器化平台实践
作者简介:郑建林,现任深圳市技研智联科技有限公司架构师,技术负责人。多年物联网及金融行业经验,对云计算、区块链、大数据等领域有较深入研究及应用。现主要从事 PaaS 平台建设,为公司各业务产品线提供平台底座如技术…...
订单服务:订单流程
订单流程 订单流程是指从订单产生到完成整个流转的过程,从而行程了一套标准流程规则。而不同的产品类型或业务类型在系统中的流程会千差万别,比如上面提到的线上实物订单和虚拟订单的流程,线上实物订单与 O2O 订单等,所以需要根据…...
Python的有用知识,一共十三个代码片段,确定不来看看吗
前言 之前发过22个小技巧,今天就来分享分享13个非常有用的代码片段 赶紧码住,看看你都了解吗 1.将两个列表合并成一个字典 假设我们在 Python 中有两个列表,我们希望将它们合并为字典形式,其中一个列表的项作为字典的键&#…...
数据结构与算法-数组
前言:几乎所有的编程语言都原生支持数组类型。因为数组是最简单的内存数据结构。创建一个数组:let arr new Array()或let arr new Array(5) // 指定长度或let arr new Array(1,2,3,4,5) // 将数组元素作为参数传给构造函数或let arr [1,2,3,4,5] // …...
PMP证书在哪个行业比较有用?
PMP 各个行业都能用,PMP 的知识体系是通用的,管理层的考试也有借鉴PMP知识的地方。历年考生考的最多的是IT 行业,其他行业也都有分布。PMP认证从国外引进大陆这么多年了,其火热程度依然不减,我个人认为是取决于市场的运…...
Wine零知识学习4 —— Wine编译进阶详解
本系列第3篇文章Wine零知识学习3 —— Winetricks介绍及下载和运行讲述了Wentricks的下载及使用。在Winetricks的使用过程中会发现很多应用下载会出现问题,会提示32位程序无法运行在64位系统上。为什么会出现这个问题?又如何解决此问题?这就是…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...









