每做一个windows项目,都会遇到种种千奇百怪的问题,无论多复杂的问题,最终都能解决,但要不是baidu的帮助和热心网友们解决问题的帖子,其中的一些问题是无法解决的。
我把最近在制作一个小软件过程中遇到的问题记录下来,来看看问题的复杂性。
将同事linux下做的*.c源代码移植到vs2010下,制作windows界面程序。
一.将*.c和*.h文件加入到vs2010工程中。
1.vs2010中无<unistd.h>头文件
2.给*.h下的函数声明加extern "C" {}
3.snprintf(),popen,pclose改为_snprintf,_popen,_pclose,
4.creat(,0755)改为open(,_S_IWRITE|_S_IREAD)
5.open(filename,O_RDONLY)改为open(filename,O_RDONLY|O_BINARY),否则后面无法正确读出文件数据。
6.为了引用方便,static函数去掉static声明。
7.将*.c加入工程后,*.c文件默认是依赖于预编译头文件的,去掉。
8..c文件不支持c++的容器作为函数参数。
二.将所有的动态库依赖改为静态库依赖。
1.将bcgcbpro改为静态库编译
(1)链接时getsystemmetrics等四个函数找不到,报error2001错误。
多亏网友的解决方案:
#pragma warning(disable:4706)
#define COMPILE_MULTIMON_STUBS
#include <multimon.h>
#pragma warning(default:4706)
(2)改为静态链接mfc库和runtime库
2.将资源动态库改为静态链接(花费了70%)的时间
这方面的官方资料是最少的,通过网友的方法和自己的摸索,最终解决了问题。
3.将openssl改为静态链接库。
(1).下载openssl源代码
(2).下载activeperl
(3).按照说明文档编译openssl为静态库
(4)区分lib文件是静态库还是dll的导入库的方法,lib /list *.lib
三.将工程的动态依赖改为静态依赖后遇到的问题
程序运行后,ListCtrl派生控件的显示出现了乱码,而在动态库下显示是正常的。
这个问题是最隐蔽的,没有任何头绪,只能一点一点,猜测,修改代码,尝试,周而复始。
最终发现问题出现在一条语句上面:
ListCtrlCl::DrawItem()
{
.........
VERIFY(GetItem(&lvi));//问题语句
............
}
通过反汇编发现VERIFY(GetItem(&lvi))对应的汇编代码为空,根本没有执行GetItem()函数,
去掉VERIFY()宏后,即
ListCtrlCl::DrawItem()
{
.........
GetItem(&lvi);
............
问题解决。VERIFY(express)是MFC的宏定义,在debug版本下,对表达式express校验,如果express为false,引发程序报错。
为何VERIFY汇编后汇编代码为空,问题肯定是出在“静态链接MFC库”的事实上,之前的MFC是动态链接的。
难道是静态链接后宏定义失效?简单求助baidu后没有答案,不想再深究下去了,还有好多工作要做。