如何解决程序/C++Dll的兼容性问题
发布网友
发布时间:2022-05-08 15:30
我来回答
共1个回答
热心网友
时间:2022-04-27 19:16
如何解决程序/C++Dll的兼容性问题
BY Sunyday丶若雪
本文将尝试解决程序与DLL在不同客户机上运行存在的兼容性问题
前言
前面的五篇文章已经将程序的核心部分全部搞定,由于我们调用了一些系统API,所以这很有可能导致程序在其他不同的客户机上无法正确运行。其实关于程序的兼容性提高在之前选择到底使用何种方法来实现某一功能时已经相当于做过一次了,由于所有的核心功能都是封装在C++DLL中的,那么C++DLL兼容性直接决定了程序的兼容性,所以提高c++DLL兼容性成为了至关重要的问题。
1)先尝试在目标客户机试运行
注意:在开发者的电脑上测试是绝对通过的,能在开发者电脑上测试通过不代表客户机能运行,由于开客户机不一定有开发者电脑的大量程序运行必要的支持框架和组件,所以先要弄清楚程序需要哪些支持框架、组件、Dll,然后再搞清哪些支持框架是客户机肯定拥有的,哪些是客户机不一定拥有的
要在客户机上测试,那么什么样的客户机是合理的:
Windows操作系统,这是必须的
编写程序界面的语言是C#,编写程序核心的语言是C++,两种语言都需要Microsoft .NET Framework的支持,由于这个程序在编写当初就没有想支持XP的意思,所以这两种语言都选用了Microsoft .NET Framework 4.5版本(XP最高支持到Microsoft .NET Framework 3.0),其实Microsoft .NET Framework 4.5算是客户机上必有的支持框架了。
大概现在就知道需要这个了,于是打开VM新建一个虚拟机,安装WIN7,再装入一个Microsoft .NET Framework 4.5支持框架,把程序拷贝进去,启动。
由于程序启动不用调用DLL.dll所以程序界面是可以打开的,继续测试功能,单击“连接”。
明明已经把DLL.dll放到了程序运行目录下,但它还是提示找不到指定模块DLL.dll
这个提示并不是找不到DLL.dll,其实是想表明DLL.dll所引用的DLL找不到,那么必须弄清楚这个DLL.dll还引用了什么其他DLL
2)查看DLL.dll引用了哪些DLL
用DLL函数查看器打开编写的DLL
查看DLL的引用,将DLL的引用信息输出TXT文件查看
这里显示一共引用了5个DLL,功能分别是:
系统支持的:
wlanapi.DLL:管理WLAN的系统DLL
RASAPI32.DLL:管理拨号的系统DLL
KERNEL32.DLL:系统内核DLL
Visual Studio 2015 C++支持的:
VCRUNTIME140.DLL:Visual Studio 2015 生成的 C++ 应用程序所需的运行时组件。
api-ms-win-crt-runtime-l1-1-0.dll:Visual Studio 2015 生成的 C++ 应用程序所需的运行时组件。
注:安装Visual C++ Redistributable Package就会为Visual Studio 2015 C++ 生成的 C++ 应用提供运行支持
通过上面的DLL分类大概可知是由于DLL.dll找不到Visual Studio 2015支持的两个DLL导致的
依据我们的DLL引用DLL时的路径寻找方法(在上一篇文章中提到过),只要把这两个DLL放到和DLL.dll相同目录下应该就OK了。
3)依据引用的DLL名称尝试找出被引用的DLL
在C盘搜索VCRUNTIME140.DLL,结果如下:
竟然有么多,这就很尴尬了,怎么确定它调用的是哪个
没办法,只能再上一个软件procexp64_V16.02(进程查看器),他可以看到所有进程调用的所有DLL以及这些被调用的DLL的位置
在开发者电脑上启动“闪讯破解”
打开procexp64_V16.02,找到“闪讯破解”,按下Ctrl+D显示闪讯破解所调用的DLL的信息
在这里只找到了VCRUNTIME140.DLL没有找到api-ms-win-crt-runtime-l1-1-0.dll;先根据procexp64_V16.02的DLL路径显示拷贝VCRUNTIME140.DLL到虚拟机应用程序下;由于没有找到api-ms-win-crt-runtime-l1-1-0.dll的真实调用路径,只能是去C盘搜索这个DLL然后随便拷贝一个过来试试了。
现在能确定系统支持的3个DLL和VCRUNTIME140.DLL是没有问题的,只能尝试运行程序
果然报错了,这次不是”找不到指定模块了“而是“试图加载不正确的程序”,这是由于引用了不正确的DLL导致的,估计就是api-ms-win-crt-runtime-l1-1-0.dll出问题了。但是毕竟C盘有这么多api-ms-win-crt-runtime-l1-1-0.dll,总不可能都一一拷贝过来尝试,看来只能另寻他法了。
4)使用静态编译生成DLL
右键点击DLL项目名,打开DLL项目属性
配置属性–C/C++–代码生成–运行库
这里的运行库有4个选项:
后面的那个’d’是代表DEBUG版本,没有’d’的就是RELEASE版本了
多线程MT的程序来说,其连接的是libcmt.lib,该文件属于C语言运行时库,整个lib都会连接到PE文件当中。
多线程MD的程序链接的却是类似msvcpXXX.dll,该文件属于微软运行时库,也就是说如果是多线程MD编译出来的文件运行时都会加载相应版本的运行时库,当如果找不到运行时库就会报错而无法运行,同时如果运行时库不匹配也会出现各种意料之外的崩溃或者程序根本跑不起来等情况。
从上面的说明可以看出由于使用的是MD方式编译,所以在运行时会调用更多的用于支持VS2015C++应用运行的DLL,为了减少调用DLL数量,选择MT编译。
注:千万不可以调用DEBUG的DLL,否则加载模块照常会出错。
选用MT后重新编译,用DLL查看器打开新生成的DLL,输出被引用DLL文件信息
发现关于VS2015的两个DLL都已经消失,只剩下三个系统的DLL
拷贝到虚拟机,尝试
单击”连接“按钮后如果能成功引用DLL中的函数,程序会进行编辑框输入文本检验
程序成功的引用了DLL中的函数,进行了编辑框输入文本检验
同时也发现,新编译的DLL大小变大了许多
5)使用 多线程MT 方式编译的弊端
成功运行程序后发现DLL变大了许多,这样就不是很好了,这是由于多线程MT编译的时候整个lib都会编译到DLL文件当中导致的。其实多线程MT编译不单单是这种缺点:如果是通过多线程MT编译方式出来的程序,那么A模块中申请的内存到B模块中释放就会出现问题,这是非常致命的。其实绝大多数软件都是采用多线程MD方式编译,如果找到他们目录很容易发现上面提到的运行时库。因为这样一来编译出来的文件小,所有运行时库统一,同时也让内存管理简单化,省去了跨模块内存访问带来的各种bug。所以多线程MD还是很好用的,能不用多线程MT就不用。
6)如何才能让多线程MD方式编译的程序在客户机正常运行
在上面在解释引用DLL各自功能中就提到过,安装Visual C++ Redistributable Package就会为Visual Studio 2015 C++ 生成的 C++ 应用提供运行支持,x64和x86最好都装上,这样程序就可以在客户机上运行了
最后在说两句
如何提高程序的兼容性
1)对于程序所使用的编程语言的必要运行环境支持必须熟知,比如C#需要安装Microsoft .NET Framework X.X,C++需要安装Visual C++ Redistributable for Visual Studio XXXX(x64和x86)
2)要学会使用DLL函数查看器、depends.exe、procexp64_V16.02来查看程序运行所依赖的dll,并不是所有客户机都有Visual C++ Redistributable for Visual Studio XXXX(x64和x86),把找到的正确的DLL直接加入程序目录。
3)在程序的安装程序中添加运行环境检测,给予没有必要运行环境的客户机强制安装必要的运行环境支持。
如何解决程序/C++Dll的兼容性问题
现在能确定系统支持的3个DLL和VCRUNTIME140.DLL是没有问题的,只能尝试运行程序 果然报错了,这次不是”找不到指定模块了“而是“试图加载不正确的程序”,这是由于引用了不正确的DLL导致的,估计就是api-ms-win-crt-runtime-l1-1-0.dll出问题了。但是毕竟C盘有这么多api-ms-win-crt-runtime-l1...
visual c++ 6.0兼容性问题及运行闪退解决方法
1.先下载一个dll文件。2.下载后解压到D:c语言vc+MicrosoftVisualStudioCommonMSDev98AddIns(路径需要看自己安装的路径。大多数人默认安装C盘,在C盘中找到MicrosoftVisualStudioCommonMSDev98,放在这条路径下)如下图所示。3.此时在搜索框中搜索cmd,选择作为管理员进行操作。4.输入代码如下。注意:此路径...
我的电脑总是提醒我应用程序错误ox0149cdll指令引用的:ox0149cdll"内...
解决方法:这可能是系统的兼容性问题,winXP的系统,右键“AutoRun.exe”文件,属性,兼容性,把“用兼容模式运行这个程序”项选择上,并选择“Windows 98/Me”。win2000如果打了SP的补丁后,只要开始,运行,输入:regsvr32 c:\winnt\apppatch\slayerui.dll。右键,属性,也会出现兼容性的选项。 例四:RealOne Gold关闭时出...
Windows7 如何解决程序兼容性问题?
如果为早期版本 Windows 编写的程序不能正确运行,则可以手动或使用程序兼容性疑难解答尝试更改程序的兼容性设置。运行程序兼容性疑难解答的步骤:1. 单击「开始」按钮,然后单击“控制面板”。2. 在搜索框中,键入“疑难解答”,然后单击“疑难解答”。 3. 在“程序”下,单击“运行为以前版本的 Windows...
电脑总是弹出应用程序错误怎么办?
应该是软件不兼容或者配置错误造成的,解决方法如下。1、首先电脑开机,弹出应用程序错误提醒,按下键盘win+r。2、然后在弹出的运行框里,输入cmd回车,如下图所示。3、接着在打开的窗口中,输入以下代码回车,如下图所示。4、这样硬盘就修复完成了,如下图所示问题解决成功了。
什么是模块兼容性问题?
3. 兼容性问题实例:假设有一个为Windows 7设计的打印机驱动程序。这个驱动程序在Windows 7上可以完美运行,但当用户尝试在Windows 10上使用它时,可能会遇到问题,因为Windows 10的打印API可能已经发生了变化。同样,如果一个老的游戏只支持Windows XP,并使用了某些在后续版本中已被弃用的API,那么这个...
应用程序或Dllc:windowssystem32\cwal_h.dll为无效的映像.请在检测一遍...
解决方法:这可能是系统的兼容性问题,winXP的系统,右键“AutoRun.exe”文件,属性,兼容性,把“用兼容模式运行这个程序”项选择上,并选择“Windows 98/Me”。win2000如果打了SP的补丁后,只要开始,运行,输入:regsvr32 c:\winnt\apppatch\slayerui.dll。右键,属性,也会出现兼容性的选项。 例三:RealOne Gold关闭时...
浏览网页老会出现这样的提示,什么原因呢?拜托了各位 谢谢
解决方法:这可能是系统的兼容性问题,winXP的系统,右键“AutoRun.exe”文件,属性,兼容性,把“用兼容模式运行这个程序”项选择上,并选择“Windows 98/Me”。win2000如果打了SP的补丁后,只要开始,运行,输入:regsvr32 c:winntapppatchslayerui.dll。右键,属性,也会出现兼容性的选项。 例四:RealOne Gold关闭时出现...
0x00000000指令引用的0x00000000内存,该内存不能为read,怎么回事...
兼容性出现了问题。电脑未安装运行环境所导致的无法运行,解决方法:1、按下键盘上的WIN+R进入到“运行”菜单,然后在运行菜单中输入“CMD”进入到命令符窗口。2、当进入到在命令符窗口中后。3、输入下图的命令来修复当前系统损坏的运行环境DLL。4、重新安装环境包。4、修复完毕后,重启电脑,软件报错...
...Components 版本与此版本的 Windows 不兼容怎么办
…”的提示框,你可以在“开始/运行”中运行Msconfig,进入系统配置实用程序对话框以后,单击选择“System.ini”标签,找出提示丢失的DLL文件,使其不被选中,这样开机时就不会出现错误提示了。如果你是XP系统:点开始---运行---输入msconfig---启动,在里面找到C:\WINDOWS\System32 \VideoAtio.dn,然...