博文

没有找到MSVCP80D.dll 解决方法(2009-08-01 17:08:00)

摘要:      在VS 2005中建立Win32工程时(以VS 2005中文版为例),你可能会遇到这样的运行错误:“没有找到MSVCP80D.dll,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。”(还可能是其它几个类似的文件:MSVCR80D.dll、MSVCM80D.dll)。对于VS2005新手,可能遇到的第一个问题便是此问题。
一直使用VC6进行开发测试,最近准备把平台转移到VS2005(过些天就应该转VS2008了,呵呵)上来。于是,决定先把CppUnit转移到此平台上来。在VS2005中编译CppUnit所遇到的问题不多,虽然没VC6方便。但是在测试编译好的CppUnit库时却遇到了困难:把以前在VC6中写的AES移植过来(其使用了CppUnit进行单元测试),在运行时却遇到了如上错误。刚开始以为可能是CppUnit没有编译好,重新编译CppUnit多次,调整编译参数,但始终有此错误,并且此错误有时出现有时不出现,这更晕了,大量时间就这样浪费了。等我静下来,才觉得可能是VS 2005的原因,于是上网搜索此错误信息,终于找到了问题所在。

VS 2005在生成可执行文件时使用了一种新的技术,该技术生成的可执行文件会伴随生成一个清单文件(manifest file)(.manifest后缀文件)(其本质上是XML文档,你可以用文本编辑器打开看看),并在链接完成后将该清单文件嵌入到exe文件中(默认情况下)。而在FAT32文件系统中,在处理清单文件阶段,当增量链接时不能完成清单文件的更新(默认情况下),于是造成清单文件嵌入失败,从而使该exe文件运行时没有相应的清单文件而运行失败并提示如上错误。

解决方案很多,列举如下:
1. 由于这是在链接动态运行库出现的问题,所以你可以选择代码生成的连接方式为/MTd而非/MDd,不用这些DLL文件从而避免问题的出现。该方法有一个很显然的缺点:适用范围有限,并且也不是我等提倡的解决问题的方式,不推荐该方法。

2. 既然跟FAT32系统有关,那么我们可以选择在NTFS文件系统中开发从而避免该问题,此方法同上,也是采用的回避问题的方式,不为我等提倡。

3. 该方法仍与FAT32有关:在项目的“属性|配置......

阅读全文(6164) | 评论:2

VC补遗之Profile篇(2009-07-26 17:27:00)

摘要:帮助你分析并发现程序运行的瓶颈,找到耗时所在,同时也能帮助你发现不会被执行的代码。从而最终实现程序的优化。 Profile的组成    Profile包括3个命令行工具:PREP,PROFILE,PLIST。可以以命令行方式运行Profile,其过程是:PREP读取应用程序的可执行文件并生成一个.PBI文件和一个.PBT文件;PROFILE根据.PBI文件,实际运行并分析程序,生成.PBO输出文件;PREP再根据.PBO文件和.PBT文件,生成新的.PBT文件;PLIST根据.PBT文件生成可阅读的输出。 Profile的具体功能    Function timing:对程序花费在执行特定函数上的时间进行评估。可以通过Profile对话框激活该功能。分析结果中,Func Time一栏以秒为单位记录了函数运行所花时间,下一栏显示了该函数时间占总运行时间的百分比;Func+Child Time栏记录了函数及其所调用的子函数运行所花的总时间,下一栏显示了前述时间占总运行时间的百分比;Hit Count栏记录函数被调用的次数;Function栏显示函数的名称。    Function coverage:记录特定函数是否被调用,可以用来确定代码中的未执行部分。可以通过Profile对话框激活该功能。分析结果列出所有被分析的函数,并使用*号标记执行过的函数。    Function counting:记录程序调用特定函数的次数。在Profile对话框中选择Custom,并在Custome Settings中指定fcount.bat(位于VC98\bin目录下)。需要注意的是,在指定fcount.bat所在目录时,最好不要用长文件名的方式,这样有可能出错,比如要将c:\Program Files写成c:\Progra~1。    Line counting:记录程序所执行的代码中特定行的次数。在Profile对话框中选择Custom,并在Custome Settings中指定lcount.bat(位于VC98\bin目录下)。该功能使用.EXE中的调试信息启动Profile,因此不需要.MAP文件。分析结果中,Line栏标示源代码的行号,Hit Count栏记录该行执行次数,下一栏显示了该行执行次数占所有代码行执行次数的百分比,Source Line显......

阅读全文(2047) | 评论:0

memcpy,memmove,strcpy,strncpy(2009-07-26 15:59:00)

摘要:memcpy与strcpy memcpy(拷贝内存内容)
相关函数 bcopy,memccpy,memcpy,memmove,strcpy,strncpy
表头文件 #include<string.h>
定义函数 void * memcpy (void * dest ,const void *src, size_t n);
函数说明 memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'\0'而结束。
返回值 返回指向dest的指针。
附加说明 指针src和dest所指的内存区域不可重叠。

strcpy(拷贝字符串)
相关函数 bcopy,memcpy,memccpy,memmove
表头文件 #include<string.h>
定义函数 char *strcpy(char *dest,const char *src);
函数说明 strcpy()会将参数src字符串拷贝至参数dest所指的地址。
返回值 返回参数dest的字符串起始地址。
附加说明 如果参数dest所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况,在编写程序时请特别留意,或者用strncpy()来取代。 char * strncpy(char *s1,char *s2,size_t n); 将字符串s2中最多n个字符复制到字符数组s1中,返回指向s1的指针。注意:如果源串长度大于n,则strncpy不复制最后的'\0'结束符,所以是不安全的,复制完后需要手动添加字符串的结束符才行。   Strcpy和Strncpy的区别- -   第一种情况:   char* p="how are you ?";   char name[20]="ABCDEFGHIJKLMNOPQRS";   strcpy(name,p); //name改变为"how are you ? "====>正确!   strncpy(name,p,sizeof(name)); //name改变为"how......

阅读全文(4554) | 评论:0

sprintf,你知道多少?(2009-07-24 16:57:00)

摘要:选自《CSDN 社区电子杂志——C/C++杂志》               printf 可能是许多程序员在开始学习C 语言时接触到的第二个函数(我猜第一个是main),说
起来,自然是老朋友了,可是,你对这个老朋友了解多吗?你对它的那个孪生兄弟sprintf 了解多
吗?在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。
由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,
后者则直接在命令行上输出。这也导致sprintf 比printf 有用得多。所以本文着重介绍sprintf,有时
也穿插着用用pritnf。
sprintf 是个变参函数,定义如下:
int sprintf( char *buffer, const char *format [, argument] ... );
除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:
格式化字符串上。
printf 和sprintf 都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的
格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终
函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。
格式化数字字符串
sprintf 最常见的应用之一莫过于把整数打印到字符串中,所以,spritnf 在大多数场合可以替代
itoa。如:
//把整数123 打印成一个字符串保存在s 中。
sprintf(s, "%d", 123); //产生"123"
可以指定宽度,不足的左边补空格:
sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"
当然也可以左对齐:
sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"
也可以按照16 进制打印:
sprintf(s, "%8x"......

阅读全文(1279) | 评论:0

回溯法N皇后(2009-07-24 15:37:00)

摘要:#include <iostream.h>
#include <math.h>
//x[i] represent to  Queen i place in row i group x[i]
void backtrack(int t);
int const n=4;//the number of queen
int x[n+1];   // the solution
int sum=0;    //teh number of the solution int nQueen()
{
 for(int i=0;i<=n;i++)
  x[i]=0;
 backtrack(1);
 return sum;
} bool placesafe(int k)
{
 for(int j=1;j<k;j++)
   if( abs(k-j)==abs(x[j]-x[k]) || (x[j]==x[k]) )//the slope is 1 or -1,or in the same group
    return false;
   return true;
} void backtrack(int t)
{
 if(t>n)
 {
  sum++;
   for(int j=1;j<=n;j++)
  {
   cout<<j<<","<<x[j]<<"#";
  }
  cout<<endl;
 }
 else
  for( int i=1;i<=n;i++)
  {
......

阅读全文(2036) | 评论:0

Linux下.pro文件的写法简介(2009-07-08 21:06:00)

摘要:1. 注释
从“#”开始,到这一行结束。 2. 指定源文件
SOURCES = *.cpp 对于多源文件,可用空格分开,如:SOURCES = 1.cpp 2.cpp 3.cpp
或者每一个文件可以被列在一个分开的行里面,通过反斜线另起一行,就像这样: SOURCES = hello.cpp \
     main.cpp
一个更冗长的方法是单独地列出每一个文件,就像这样:     SOURCES += hello.cpp
    SOURCES += main.cpp 这种方法中使用“+=”比“=”更安全,因为它只是向已有的列表中添加新的文件,而不是替换整个列表。 3. 指定头文件
HEADERS = hello.h或者HEADERS += hello.h 列出源文件的任何一个方法对头文件也都适用。 4. 配置信息
CONFIG用来告诉qmake关于应用程序的配置信息。     CONFIG += qt warn_on release 在这里使用“+=”,是因为我们添加我们的配置选项到任何一个已经存在中。这样做比使用“=”那样替换已经指定的所有选项是更安全的。
A> qt部分告诉qmake这个应用程序是使用Qt来连编的。这也就是说qmake在连接和为编译添加所需的包含路径的时候会考虑到Qt库的。
B> warn_on部分告诉qmake要把编译器设置为输出警告信息的。
C> release部分告诉qmake应用程序必须被连编为一个发布的应用程序。在开发过程中,程序员也可以使用debug来替换release 5. 指定目标文件名
TARGET = filename 如果不设置该项目,目标名会被自动设置为跟项目文件一样的名称 6. 添加界面文件(ui)
INTERFACES = filename.ui 7. 平台相关性处理
我们在这里需要做的是根据qmake所运行的平台来使用相应的作用域来进行处理。为Win......

阅读全文(3631) | 评论:0

学习C++的50条建议(转麦克老狼)(2009-07-07 15:37:00)

摘要:学习C++的50条建议   -->
1. 把C++当成一门新的语言学习;
2. 看《Thinking In C++》,不要看《C++变成死相》;
3. 看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为他们很难而我们自己是初学者所以就不看;
4. 不要被VC、BCB、BC、MC、TC等词汇所迷惑——他们都是集成开发环境,而我们要学的是一门语言;
5. 不要放过任何一个看上去很简单的小编程问题——他们往往并不那么简单,或者可以引伸出很多知识点;
6. 会用Visual C++,并不说明你会C++;
7. 学class并不难,template、STL、generic programming也不过如此——难的是长期坚持实践和不遗余力的博览群书;
8. 如果不是天才的话,想学编程就不要想玩游戏——你以为你做到了,其实你的C++水平并没有和你通关的能力一起变高——其实可以时刻记住:学C++是为了编游戏的;
9. 看Visual C++的书,是学不了C++语言的;
10. 浮躁的人容易说:XX语言不行了,应该学YY;——是你自己不行了吧!?
11. 浮躁的人容易问:我到底该学什么;——别问,学就对了;
12. 浮躁的人容易问:XX有钱途吗;——建议你去抢银行;
13. 浮躁的人容易说:我要中文版!我英文不行!——不行?学呀!
14. 浮躁的人容易问:XX和YY哪个好;——告诉你吧,都好——只要你学就行;
15. 浮躁的人分两种:a)只观望而不学的人;b)只学而不坚持的人;
16. 把时髦的技术挂在嘴边,还不如把过时的技术记在心里;
17. C++不仅仅是支持面向对象的程序设计语言;
18. 学习编程最好的方法之一就是阅读源代码;
19. 在任何时刻都不要认为自己手中的书已经足够了;
20. 请阅读《The Standard C++ Bible》(中文版:标准C++宝典),掌握C++标准;
21. 看得懂的书,请仔细看;看不懂的书,请硬着头皮看;
22. 别指望看第一遍书就能记住和掌握什么——请看第二......

阅读全文(1273) | 评论:0

extern用法详解(转)(2009-07-07 15:32:00)

摘要:1 基本解释
  extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。
  另外,extern也可用来进行链接指定。 2 问题:extern 变量
  在一个源文件里定义了一个数组:char a[6];
  在另外一个文件里用下列语句进行了声明:extern char *a;
  请问,这样可以吗?
  答案与分析:
  1)、不可以,程序运行时会告诉你非法访问。原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]。
  2)、例子分析如下,如果a[] = "abcd",则外部变量a=0x61626364 (abcd的ASCII码值),*a显然没有意义
  显然a指向的空间(0x61626364)没有意义,易出现非法内存访问。
  3)、这提示我们,在使用extern时候要严格对应声明时的格式,在实际编程中,这样的错误屡见不鲜。
  4)、extern用在变量声明中常常有这样一个作用,你在*.c文件中声明了一个全局的变量,这个全局的变量如果要被引用,就放在*.h中并用extern来声明。
4 问题:extern 函数2
  当函数提供方单方面修改函数原型时,如果使用方不知情继续沿用原来的extern申明,这样编译时编译器不会报错。但是在运行过程中,因为少了或者多了输入参数,往往会照成系统错误,这种情况应该如何解决?
  答案与分析:
  目前业界针对这种情况的处理没有一个很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供对外部接口的声明,然后调用方include该头文件,从而省去extern这一步。以避免这种错误。
  宝剑有双锋,对extern的应用,不同的场合应该选择不同的做法。 5 问题:extern “C”
  在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,应该如何解决这种情况呢?   答案与分析:
  C++语言在编译的时候为了解决函数的多态......

阅读全文(1385) | 评论:0

VC2005去掉烦人的warning C4996: '×××' was decl(2009-06-18 10:06:00)

摘要:解决方法:在项目属性页-->配置属性-->C/C++-->预处理器-->预处理器定义 添加;_CRT_SECURE_NO_DEPRECATE 注意:Debug和Release都要添加 附:微软说非安全库函数sprintf、sscanf、strcpy等都是不安全的,应该用sprintf_s、sscanf_s、strcpy_s取代。......

阅读全文(1822) | 评论:0

BLOB读写数据(2009-06-17 16:55:00)

摘要:/*!
*Connect to the database acorrding to the information reading form the configure file
*\return   mysqlpp::Connection ->the connection if success,else exit
*/
MYSQL* connectToDB(  )
{    
 
 MYSQL* mysql=mysql_init(NULL);  
 try
 { 
 
    if( mysql_real_connect(mysql,this->confg_.host_name,this->confg_.user_name,this->confg_.password,this->confg_.db_name,3306,NULL,0))
    {
     std::cout<<"mysql_real_connect() succeed"<<std::endl;
    }
    else
    {
     std::cout<<"mysql_real_connect() failed"<<std::endl;
    }
    return mysql;
 }
 catch (std::exception& er)
 {
  std::cerr << "Connection failed: " << er.what() << ......

阅读全文(5300) | 评论:0