随笔 - 6, 文章 - 0, 评论 - 5, 引用 - 0
数据加载中……

2009年8月8日

VC.net 2005找不到MSVCR80D.dll的完美解决方案

[分享]VC.net 2005找不到MSVCR80D.dll的完美解决方案
 




 问题描述:大部分的vs.net 2005的用户在新建“win32项目-windows应用程序”的时候,新建的工程都通不过去,出现如下提示:

Solution to “MSVCR80D.dll not found”.

没有找到MSVCR80D.dll,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。

 

问题所在:由于vs.net 2005 采用了一种新的DLL方案,搞成一个exe还要配有一个manifest文件(一般在嵌入文件里了,所以看不到,不过也可以不嵌入,这样会生产一个<程序名>.exe.manifest的文件,没它exe自己就转不了了:)这是个新功能,微软弄了个新工具(mt.exe),结果不好用,好像是fat32下时间戳有问题(在ntfs下这个问题就没有了),搞得manifest有时嵌入不到exe中(默认配置是嵌入的,所以就报错找不到dll了。

 

解决方案:

1    微软对于这个问题应该也有处理,不过感觉不是很人性化。在“属性->配置属性->清单工具->常规下有一个”使用FAT32解决办法,把它选成是,就可以了。(注意:一定要先配置这个选项,然后再编译工程,要不然还是不好用:)

2    找到你的工程的文件夹,如(myproject),找到其下的myproject\myproject\Debug\ myproject.rec,把它删掉(删掉整个Debug目录也可以),重新编译,搞定!

 

3    本解决方案可以直接再应用向导中配置,严重符合高级人机界面要求:

1    首先找到你的vs.net安装目录(如我的是E:\Program Files\Microsoft Visual Studio 8),定位到Microsoft Visual Studio 8\VC\VCWizards\AppWiz\Generic\Application文件夹,备份这个Application文件夹,不然一会你自己改咂了我可不管啊:)。

2    打开html\2052,看到两个文件了吧,就那个AppSettings.htm了,这个管着你的那个配置向导的界面,用UE(不要告诉我你不知道ue啥东西,baidu it)打开,在266“                </SPAN>”后回车,然后插入一下内容:

<!-- this (hua)section is added by HUA. -->

                   <BR><BR><BR><BR><BR>

                    

                <SPAN class='itemTextTop' id='FILE_SYSTEM_SPAN' title=''>选择你所使用的文件系统:

                    

                       <P CLASS='Spacer'>&nbsp</P>

                    

                        <INPUT TYPE='radio' CLASS='Radio' checked onPropertyChange='' NAME='filesystem' ID='FAT32' ACCESSKEY='F' TITLE='FAT32'>

                        <DIV CLASS='itemTextRadioB' ID='FAT32_DIV' TITLE='FAT32'>

                        <LABEL FOR='FAT32' ID='FAT32_LABEL'>FAT32(<U>F</U>)</LABEL>

                        </DIV>

 

                      <BR>

 

                        <INPUT TYPE='radio' CLASS='Radio' onPropertyChange='' NAME='filesystem' ID='NTFS' ACCESSKEY='N' TITLE='NTFS'>

                        <DIV CLASS='itemTextRadioB' ID='NTFS_DIV' TITLE='NTFS'>

                        <LABEL FOR='NTFS' ID='NTFS_LABEL'>NTFS(<U>N</U>)</LABEL>

                        </DIV>

                </SPAN>

<!-- end of (hua)section -->

好,保存关闭,这个改完了,准备下一个。

 

3    打开scripts\2052,这里就一个文件,ue打开它,找到138“        var bATL = wizard.FindSymbol('SUPPORT_ATL');”其后回车,插入如下内容:

// this (hua)section is added by HUA.        

        var bNTFS = wizard.FindSymbol('FILE_SYSTEM_SPAN');

// end of (hua)section    

        好,继续找到210(源文件的210,你加了上边的语句就不是210了:)“        config = proj.Object.Configurations.Item('Release');”意这次要在这行“前边”加如下内容

// this (hua)section is added by HUA.

       if(!bNTFS)

        {

            var MFTool = config.Tools('VCManifestTool');

            MFTool.UseFAT32Workaround = true;

        }

// end of (hua)section

该段内容解决了在向导下不点“下一步”而直接点“完成”来生成一个win32控制台项目时,则未能自动设置UseFAT32Workaround属性的值为true。

 

posted @ 2009-08-08 09:29 qhmao 阅读(460) | 评论 (1)编辑 收藏

2009年5月6日

const * * const


1.const int *r=&x; //声明r为一个指向常量的x的指针,r指向的对象不能被修改,但他可以指向任何地址的常量。

先是一个指针 *r,则*r所指的对象不可被修改。

2.int const *r=&x; //与用法1完全等价,没有任何区别。

3.int * const r=&x; //声明r为一个常量指针,他指向x,r这个指针的指向不能被修改,但他指向的地址的内容可以修改。

先是一个常量,则其值不可修改,

4.const int * const r=&x; //综合1、3用法,r是一个指向常量的常量型指针。



原文: http://www.fjtu.com.cn/fjnu/courseware/1308/course/_source/web/lesson/chapter9/j5.htm

第五节  const 指针

  对于下面涉及指针定义和操作的语句:
    int a=1;
    int *pi;
    pi=&a;
    *pi=58;

  可以看到,一个指针涉及到两个变量,指针本身pi和指向的变量a。修改这两个变量的对应操作为“pi=&a;”和“*pi=58;”。

1.指向常量的指针(常量指针)

  在指针定义语句的类型前加const,表示指向的对象是常量。例如:
    const int a=78;
    const int b=28;
    int c=18;
    const int*pi=&a; //指针类型前力口const
    *pi=58; //error:不能修改指针指向的常量
    pi=&b; //ok:指针值可以修改
    *pi=68; //error:同上
    pi=&c;
    *pi=88; //error:同上
    c=98; //ok

  a是常量,将a的地址赋给指向常量的指针pi, 使a的常量性有了保证。如果企图修改a,则会引起“不能修改常量对象”(Cannot modify a const object)的编译错误。
  可以将另一个常量地址赋给指针“pi=&b;” (指针值可以修改),这时,仍不能进行“*p =68;”的赋值操作,从而保护了被指向的常量不被修改。 见图8-4,图中阴影部分表示不能


图8-4 指向常量的指针

  被修改。可以将一个变量地址赋给指针“pi=&c;”, 这时,由于不能进行“*pi=88;”的赋值操作,从而保护了被指向的变量在指针操作中不被修改。定义指向常量的指针只限制指针的间接访问操作,而不能规定指针指向的值本身的操作规定性。例如,变量c可以修改,这在 函数传递中经常被使用。
  例如,下面的程序将两个一样大小的数组传递给一个函数,让其完成复制字符串的工作,为了防止作为源数据的数组遭到破坏,声明该形参为常量字符串:
    //**********************
    //**   ch8_10.cpp  **
    //**********************

    #include <iostream.h>

    void mystrcpy(char* dest, const char* source)
    {
     while(*dest++ = *source++);
    }

    void main()
    {
     char a[20]="How are you!";
     char b[20];
     mystrcpy(b,a);
     cout <<b <<endl;
    }

  运行结果为:
    How are you!

  变量字符串a传递给函数mystrcpy()中的source, 使之成为常量,不允许进行任何修改、但在主函数中, a却是一个普通数组,没有任何约束,可以被修改。
  由于数组a不能直接赋值给b, 所以通过一个函数实现将数组a的内容复制给数组b。
  函数mystrcpy()中的语句是一个空循环,条件表达式是一个赋值语句。随着一个赋值动作,便将一个a数组中的字符赋给了b数组中对应的元素,同时两个数组参数都进行增量操作以指向下一个元素。只要所赋的字符值不是'\0',(条件表达式取假值),则循环就一直进行下去。 ,
  常量指针定义"const int *pi=&a;”告诉编译,*pi是常量,不能将,pi作为左值进行操作。

2.指针常量

  在指针定义语句的指针名前加const,表示指针本身是常量。例如:
    char *constpc="asdf"; //指针名前加const定义指针常量
    pc="dfgh"; //error:指针常量不能改变其指针值
    *pc='b'; //ok:pc内容为,'bsdf',
    *(pc+1)='c'; //ok:pc内容为'bcdf',
    *pc++='y'; //error:指针常量不能改变其指针值
    const int b=28;
    int* const pi=&b; //error:不能将const int*转换成int*

  pc是指针常量,在定义指针常量时必须初始化,就像常量初始化一样。这里初始化的 值是字符串常量的地址,见图8_5

 


图8_5 指向变量的指针常量图

  由于pc是指针常量,所以不能修改该指针值。“pc="dfgh";”将引起一个“不能修改常量对象”(Cannot modify a const object)的编译错误。
  pc所指向的地址中存放的值并不受指针常量的约束,即*pc不是常量,所以“*pc='b';”和“*(pc+1)='c';”的赋值操作是允许的。但“*pc++=y;”是不允许的,因为该语句修改*pc的同时也修改了指针值。
  由于此处*pi是不受约束的,所以,将一个常量的地址赋给该指针“int* const pi=&b;”是非法的,它将导致一个不能将const int *转换成int *的编译错误,因为那样将使修改常量(如:“* pi=38;”)合法化。
  指针常量定义"int *const pc=&b;”告诉编译,pc是常量,不能作为左值进行操作,但是允许修改间接访问值,即*pc可以修改。

3.指向常量的指针常量(常量指针常量)

  可以定义一个指向常量的指针常量,它必须在定义时进行初始化。例如:
    const int c=7;
    int ai;
    const in * const cpc=&ci; //指向常量的指针常量
    const int * const cpi=&ai; //ok
    cpi=&ci; //error:指针值不能修改
    *cpi=39; //error:不能修改所指向的对象
    ai=39; //ok

  cpc和cpi都是指向常量的指针常量,它们既不允许修改指针值,也不允许修改*cpc的值,见图8-6。

 


图8—6 指向常量的指针常量

  如果初始化的值是变量地址(如&ai), 那么不能通过该指针来修改该变量的值。也即“*cpi=39;”是错误的,将引起“不能修改常量对象”(Cannot modify a const object)的编译错误。但“ai=39;”是合法的。
  常量指针常量定义“coastint * coastcpc=&b;”告诉编译,cpc和* cpc都是常量,它们都不能作为左值进行操作

posted @ 2009-05-06 18:24 qhmao 阅读(151) | 评论 (4)编辑 收藏

2009年4月17日

gdb和g++的简单使用

在编译之前我们需要在系统里安装G++ GCC,它们就是Linux下的C++/C的编译器。代码如下

代码:


sudo apt-get install build-essential


好,现在我们在文本编辑器里写一个C的简单的程序(好像所有学习C或者C++的书都会出现)

代码:


include <stdio.h>
int main()
{
    printf("Hello,World!\n");
    return 0;
}


现在存盘为Hello.c,打开你的终端,并在文件当前目录输入:

代码:


gcc Hello.c -o hello   


编译时可能会出现如下警告:no newline at and of file ,只有在文件结尾添加一个新行就好了。
然后在终端中输入 ./hello ,你就能在终端中看到程序运行结果了。

下面来说下C++是如何编译的
写程序(不用我多说了吧)

代码:


#include <iostream>
using namespace std;
int main()
{
    cout<<"Hello,World!\n"<<endl;
    return 0;
}


存盘为Hello.cpp
使用gcc编译??? 不对,这里我们使用g++来编译C++程序

代码:


g++ Hello.cpp -o hello



编译多个文件我们怎么办??? 来看下面出了三个文件Hello.h, Hello.cpp, MyFirst.cpp

代码:


//file_NO1:Hello.h
class Hello {
     Hello();
     void Display();
}
//file_NO2:Hello.cpp
#include <iostream>
#include "Hello.h"
using namespace std;
Hello::Hello()
{
}
Hello::Display()
{
    cout<<"Hello,World!\n"<<endl;
}
//file_NO3:MyFirst.cpp
#include <iostram>
#include "Hello.cpp"
int main()
{
    Hello theHello;
    theHello->Display();
    return 0;
}


g++中有一个参数-c 可以只编译不连接,那么我们就可以按如下顺序编译文件,

代码:


g++ -c Hello.cpp -o Hello.o
g++ -c MyFirst.cpp -o MyFirst.o
g++ MyFirst.o hello.o -o MyFirst


你是否会问,如果是一个项目的话,可能会有上百个文件,这样的编译法,人不是要累死在电脑前吗,或者等到你编译成功了,岂不是头发都白了,呵呵,所以我们要把上述的编译过程写进以下一个文本文件中:
Linux
下称之为makefile
[code]
#
这里可以写一些文件的说明
MyFirst: MyFirst.o hello.o
g++ MyFirst.o hello.o -o MyFirst
Hello.o:Hello.cpp
g++ -c Hello.cpp -o Hello.o
MyFirst.o:MyFirst.cpp
g++ -c MyFirst.cpp -o MyFirst.o
[\code]
存盘为MyFirst,在终端输入:make MyFist ,程序出现了错误可是所有程序员共同的敌人,在编写程序时我们应该尽量的去避免错误的出现,不过编写的时候再怎么都不可避免的出现这样那样的错误,对程序 进行必要的调试是一个好主意,那我们怎么来调试程序呢,看下面:
[code]
gdb ./
文件名 ////////////////在这里我修改下要想下面可以调试,在上面编译的 时候必须加上参数gg++ -g hello.cpp -o hello
[/code]
以下为调试状态下的可以用到的命令(可以仅输入单词的输入,如break可简为b),尖括号中为说明
[code]
list <
显示源代码>
break
行号 <设置断点>
run <
运行程序>
continue <
继续从断点处执行>
print
变量 <调试时查看变量的值>
del
行号 <删除断点>
step <
单步执行,可跟踪到函数内部>
next <
单步执行,不可跟踪到函数内部>
quit <
退出>
[/code]


原文地址:http://www.cppblog.com/heidaizx/articles/33582.html

posted @ 2009-04-17 23:18 qhmao 阅读(503) | 评论 (0)编辑 收藏

g++ Hello World

#include <iostream>
using namespace std;
int main()
{
    cout << "Hello , World \n" << endl;
    return 0;
}


g++  Hello.cpp -o tester

./tester

posted @ 2009-04-17 23:15 qhmao 阅读(439) | 评论 (0)编辑 收藏

2009年4月8日

UltraEdit的文件标签不见了.

挂 过多次,,,,,,这次要长脑子,写下来。。。。。。。。。。

点 视图->视图/列表(V)->打开文件标签(E)

posted @ 2009-04-08 09:20 qhmao 阅读(540) | 评论 (0)编辑 收藏

2009年3月26日

static变量和static函数

在C语言编程中,static的一个作用是信息屏蔽!

比方说,你自己定义了一个文件 -- 该文件中有一系列的函数以及变量的声明和定义!

你希望该文件中的一些函数和变量只能被该文件中的函数使用,那么,你可以在该函数、变量的前面加上static,代表他们只能被当前文件中的函数使用!


而在C++中,用static来作为信息屏蔽就显得没有必要了!因为,C++有了信息屏蔽的利器 -- class机制!

类中的private属性的变量和函数就对外禁止访问!


然后是C/C++通用的函数作用域的static型的变量!其目的,也是为了信息的屏蔽!


int fun() {
   static int a = 1;
   a++;
}

在第一次进入这个函数的时候,变量a被初始化为1!并接着自增1!

以后每次进入该函数,a就不会被再次初始化了,仅进行自增1的操作!

在static发明前,要达到同样的功能,则只能使用全局变量:

int a = 1;

int fun() {
   a++;
}

那么,a的值就有可能被其他函数所改变!



最后,说说类中的static变量和函数。


这种存储属性的变量和函数是同一种类的不同实例之间通信的桥梁!


#include <iostream>
using namespace std;

class A {
public:
    static int num;    //    统计创建了多少个实例
    A () {num++};    //    每创建一个实例,就让num自增1

    //    返回通过构造函数所创建过的A类实例的数目
    static int how_many_instance() {
        return num;
    }
}

static A::num = 0;    //    需要在类申明的外部单独初始化!


int main() {
    cout << A::how_many_instance() << endl;
    A a, b, c, d;
    cout << A::how_many_instance() << endl;
    system("pause");
}


一般,在类内部,是通过static属性的函数,访问static属性的变量!

补充一点,在类中,static型的成员函数,由于是类所拥有的,而不是具体对象所有的,这一点对于windows的回调机制非常有用。
因为对于回调函数而言,windows不会借助任何对象去调用它,也就不会传递this指针,那么对于一般成员函数作为回调函数的后果,就是堆栈中有一个随机的变量会成为this指针,这当然会引发程序的崩溃。
而static函数,由于是整个类的,屏蔽了this指针。因此,如果成员函数作为回调函数,就应该用static去修饰它。
(引用,原文:http://www.cppblog.com/dbkong/archive/2009/03/02/16169.html

posted @ 2009-03-26 12:05 qhmao 阅读(297) | 评论 (0)编辑 收藏