目录
一、vs2013 32 DLL 转 VS2022 64 DLL 所遇问题
1、 LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1800”不匹配值“1900”
2、原先VS2013 现在 VS2022 导致的vsnprintf 重定义问题
3、 无法解析的外部符号 __vsnwprintf_s
4、无法解析的外部符号__imp__CertFreeCertificateContext
5、无法解析的外部符号__iob_func
6、LNK1218: 警告被视为错误 - 没有生成“object”文件
7、end()找不到
8、使用64位openssl库
9、优化策略 或 运行时库 尽量一致
10、当前不会命中断点,源代码与原始版本不同
本打算用VS2013 编译64位的,结果 集成到vs2022 中时,因为所用的C++标准不同,因此导致不兼容,只能用VS2022 重新编译下,期间 编译优化策略也要保持一致,这里都禁止优化。
一、vs2013 32 DLL 转 VS2022 64 DLL 所遇问题
1、 LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1800”不匹配值“1900”
You are trying to link objects compiled by different versions of the compiler. That’s not supported in modern versions of VS, at least not if you are using the C++ standard library. Different versions of the standard library are binary incompatible and so you need all the inputs to the linker to be compiled with the same version. Make sure you re-compile all the objects that are to be linked.
The compiler error names the objects involved so the information the question already has the answer you are looking for. Specifically it seems that the static library that you are linking needs to be re-compiled.
你在尝试着将编译自不同版本编译器的对象链接起来。在现代版本的 VS 中这是不被支持的,至少在你使用了 C++ 标准库之后就不支持了。不同版本的标准库之间是二进制不兼容的,因此你需要使用统一版本的编译器来编译其所有的输入文件。请你需要链接的对象都全部重新编译了。
使用VS2022 重新编译下
_MSC_VER 为 1800,对应了 Visual Studio 2013
2、原先VS2013 现在 VS2022 导致的vsnprintf 重定义问题
在宏定义处,加上编译版本选择
#if defined(_MSC_VER)&&_MSC_VER<1900
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define vsnwprintf _vsnwprintf
#endif
3、 无法解析的外部符号 __vsnwprintf_s
error LNK2019: 无法解析的外部符号 __vsnwprintf_s
原因:vs2015以上 默认编译时将许多标准库采用内联方式处理,因而没有可以链接的标准库文件,所以要专门添加标准库文件来链接标准库中的函数
工程->右键属性->链接器->输入->附加依赖项 添加 legacy_stdio_definitions.lib
4、无法解析的外部符号__imp__CertFreeCertificateContext
因为openssl库使用了windows的一个密码学库: Crypt32
也把它加上
Crypt32.lib
legacy_stdio_definitions.lib
5、无法解析的外部符号__iob_func
在 VS2015 以上中 __iob_func
改成了 __acrt_iob_func,所以代码中需要增加一个
名为 __iob_func 转换函数
在头文件中,
添加转换函数
#if _MSC_VER>=1900
#include "stdio.h"
_ACRTIMP_ALT FILE* __cdecl __acrt_iob_func(unsigned);
#ifdef __cplusplus
extern "C"
#endif
FILE* __cdecl __iob_func(unsigned i) {
return __acrt_iob_func(i);
}
#endif /* _MSC_VER>=1900 */
6、LNK1218: 警告被视为错误 - 没有生成“object”文件
已经设置了否,还是有这个错误
后来发现,连接器哪里 还有个链接器 警告视为错误
7、end()找不到
改为 : std::map<_Kty, _Ty>::end()
template<typename _Kty=size_t,typename _Ty=void*>
class CSafeMap
: protected std::map<_Kty,_Ty>
{
CMyMutex m_mutex;
public:
typedef int(*ENUM_SAFE_MAP)(_Kty,_Ty,void*);
_Ty lockedFind(_Kty seq) {
_Ty p=0;
typename std::map<_Kty,_Ty>::iterator it=std::map<_Kty,_Ty>::find(seq);
#ifdef _WIN32
if(it!= std::map<_Kty, _Ty>::end()) {
#else
if(it!=std::map<_Kty,_Ty>::end()) {
#endif
p=it->second;
}
return p;
}
void lockedAdd(_Kty seq,_Ty p) {
#ifdef _WIN32
std::map<_Kty, _Ty>::insert(std::make_pair(seq,p));
#else
std::map<_Kty,_Ty>::insert(std::make_pair(seq,p));
#endif
}
_Ty lockedRemove(_Kty seq) {
_Ty p=0;
typename std::map<_Kty,_Ty>::iterator it=std::map<_Kty,_Ty>::find(seq);
#ifdef _WIN32
if(it!= std::map<_Kty, _Ty>::end()) {
#else
if(it!=std::map<_Kty,_Ty>::end()) {
#endif
p=it->second;
#ifdef _WIN32
std::map<_Kty, _Ty>::erase(it);
#else
std::map<_Kty,_Ty>::erase(it);
#endif
}
return p;
}
8、使用64位openssl库
一开始编译很多错误,后来意识到,可能使用的openssl库,是32位的,所以网上又找了64位的编译后,才走上正轨。
9、优化策略 或 运行时库 尽量一致
如果还有问题,可以将dll 、目标工程,采用同样的优化策略
还不行的话,运行库 可设置为一样 后试试
,
10、当前不会命中断点,源代码与原始版本不同
方法: 选中这个CPP中全部代码,编辑-》高级-》设置选定内容的格式 ,如果这样还不行的话,网上再搜索其它方法,我是这样好的。