colorful

zc qq:1337220912

 

同步/异步与阻塞/非阻塞的区别消息

http://vrlinux.com/wenzhangjingxuan/20100908/75026.html

我喜欢用自己的语言通过联系现实生活中的一些现象解释一些概念,当我能做到这一点时,说明我已经理解了这个概念.今天要解释的概念是:同步/异步与阻塞/非阻塞的区别.

这两组概念常常让人迷惑,因为它们都是涉及到IO处理,同时又有着一些相类似的地方.

首先来解释同步和异步的概念,这两个概念与消息的通知机制有关.

举个例子,比如我去银行办理业务,可能选择排队等候,也可能取一个小纸条上面有我的号码,等到排到我这一号时由柜台的人通知我轮到我去办理业务了.
前 者(排队等候)就是同步等待消息,而后者(等待别人通知)就是异步等待消息.在异步消息处理中,等待消息者(在这个例子中就是等待办理业务的人)往往注册 一个回调机制,在所等待的事件被触发时由触发机制(在这里是柜台的人)通过某种机制(在这里是写在小纸条上的号码)找到等待该事件的人.
而在实际的程序中,同步消息处理就好比简单的read/write操作,它们需要等待这两个操作成功才能返回;而异步处理机制就是类似于select/poll之类的多路复用IO操作,当所关注的消息被触发时,由消息触发机制通知触发对消息的处理.

其次再来解释一下阻塞和非阻塞,这两个概念与程序等待消息(无所谓同步或者异步)时的状态有关.
继 续上面的那个例子,不论是排队还是使用号码等待通知,如果在这个等待的过程中,等待者除了等待消息之外不能做其它的事情,那么该机制就是阻塞的,表现在程 序中,也就是该程序一直阻塞在该函数调用处不能继续往下执行.相反,有的人喜欢在银行办理这些业务的时候一边打打电话发发短信一边等待,这样的状态就是非 阻塞的,因为他(等待者)没有阻塞在这个消息通知上,而是一边做自己的事情一边等待.但是需要注意了,第一种同步非阻塞形式实际上是效率低下的,想象一下 你一边打着电话一边还需要抬头看到底队伍排到你了没有,如果把打电话和观察排队的位置看成是程序的两个操作的话,这个程序需要在这两种不同的行为之间来回 的切换,效率可想而知是低下的;而后者,异步非阻塞形式却没有这样的问题,因为打电话是你(等待者)的事情,而通知你则是柜台(消息触发机制)的事情,程 序没有在两种不同的操作中来回切换.

很多人会把同步和阻塞混淆,我想是因为很多时候同步操作会以阻塞的形式表现出来,比如很多人会写阻塞 的read/write操作,但是别忘了可以对fd设置O_NONBLOCK标志位,这样就可以将同步操作变成非阻塞的了;同样的,很多人也会把异步和非 阻塞混淆,因为异步操作一般都不会在真正的IO操作处被阻塞,比如如果用select函数,当select返回可读时再去read一般都不会被阻塞,就好 比当你的号码排到时一般都是在你之前已经没有人了,所以你再去柜台办理业务就不会被阻塞.

可见,同步/异步与阻塞/非阻塞是两组不同的概念,它们可以共存组合,也可以参见这里:
http://www.ibm.com/developerworks/cn/linux/l-async/

----------------------------------------- 分割线 ------------------------------------------------------
昨晚写完这篇文章之后,今早来看了看反馈,同时再自己阅读了几遍,发现还是有一些地方解释的不够清楚,在这里继续补充完善一下我的说法,但愿没有越说越糊涂.

同步和异步:上面提到过,同步和异步仅仅是关于所关注的消息如何通知的机制,而不是处理消息的机制.也就是说,同步的情况下,是由处理消息者自己去等待消息是否被触发,而异步的情况下是由触发机制来通知处理消息者,所以在异步机制中,处理消息者和触发机制之间就需要一个连接的桥梁,在我们举的例子中这个桥梁就是小纸条上面的号码,而在select/poll等IO多路复用机制中就是fd,当消息被触发时,触发机制通过fd找到处理该fd的处理函数.

请注意理解消息通知和处理消息这 两个概念,这是理解这个问题的关键所在.还是回到上面的例子,轮到你办理业务这个就是你关注的消息,而去办理业务就是对这个消息的处理,两者是有区别的. 而在真实的IO操作时,所关注的消息就是该fd是否可读写,而对消息的处理就是对这个fd进行读写.同步/异步仅仅关注的是如何通知消息,它们对如何处理 消息并不关心,好比说,银行的人仅仅通知你轮到你办理业务了,而如何办理业务他们是不知道的.

而很多人之所以把同步和阻塞混淆,我想也是 因为没有区分这两个概念,比如阻塞的read/write操作中,其实是把消息通知和处理消息结合在了一起,在这里所关注的消息就是fd是否可读/写,而 处理消息则是对fd读/写.当我们将这个fd设置为非阻塞的时候,read/write操作就不会在等待消息通知这里阻塞,如果fd不可读/写则操作立即 返回.

很多人又会问了,异步操作不会是阻塞的吧?已经通知了有消息可以处理了就一定不是阻塞的了吧?
其实异步操作是可以被阻塞住的,只不过通常不是在处理消息时阻塞,而是在等待消息被触发时被阻塞. 比如select函数,假如传入的最后一个timeout参数为NULL,那么如果所关注的事件没有一个被触发,程序就会一直阻塞在这个select调用 处.而如果使用异步非阻塞的情况,比如aio_*组的操作,当我发起一个aio_read操作时,函数会马上返回不会被阻塞,当所关注的事件被触发时会调 用之前注册的回调函数进行处理,具体可以参见我上面的连接给出的那篇文章.回到上面的例子中,如果在银行等待办理业务的人采用的是异步的方式去等待消息被 触发,也就是领了一张小纸条,假如在这段时间里他不能离开银行做其它的事情,那么很显然,这个人被阻塞在了这个等待的操作上面;但是呢,这个人突然发觉自 己烟瘾犯了,需要出去抽根烟,于是他告诉大堂经理说,排到我这个号码的时候麻烦到外面通知我一下(注册一个回调函数),那么他就没有被阻塞在这个等待的操 作上面,自然这个就是异步+非阻塞的方式了.

 

posted @ 2012-03-29 11:53 多彩人生 阅读(354) | 评论 (0)编辑 收藏

Qt安装—搭建VS2008+QT开发环境

http://blog.csdn.net/mac_cm/article/details/6591168

Qt安装—搭建VS2008+QT开发环境

  (一)工欲善其事,必先利其器,废话不多讲。

      总结起来网上流行的VS2008+QT安装说明有以下几个问题需要解释清楚:
     1,首先明确需要下载什么版本的QT。网上流行的安装说明只是针对过去旧版本的QT,还有要求下载VS2008 SP1补丁的等等。很乱,对于刚接触Qt开发者会造成不必要的困扰,安装个开发环境真的需要那么繁琐和劳神吗
     2,对于环境变量的配置,诸如path,QTDIR 和WindowsSdkDir等等。实际上都是旧版本的Qt,新版本的Qt已经不需要设置了。
     3,真的必须要configure 和nmake QT吗?对于漫长的编译过程和七七八八的编译错误?我们完全没有不必要折腾了,这里我们下载已经编译好的QT版本就够了,估计QT版本4.6以下需要这样做。     

(二)对于以上的问题,我是按照网上说法大费周折无果,实际新版本的Qt安装起来非常简单。

      第一步:安装VS2008,我这里安装的是中文版的VS2008并且也没有安装VS2008 SP1,对于VS2008的安装过程这里省略了。

      第二步:安装Qt,访问Qt官方网站http://qt.nokia.com/downloads-cn下载2个软件:

      1,下载VS2008编译好的QT4.7版本:http://get.qt.nokia.com/qt/source/qt-win-opensource-4.7.0-vs2008.exe
      提示:minGW版本不用下,他是minGW工具编译下的QT库。QTSDK-qt-sdk-win-opensource-2010.05.exe 也不用下载,它是用QT独立进行开发下的完整软件安装包,安装过程与一般软件相同,点击下一步就行了。

      2,下载VS2008的Qt插件:http://get.qt.nokia.com/vsaddin/qt-vs-addin-1.1.7.exe
      提示:这是个针对VS(VS2005、VS2008、VS2010)各个版本都适用的QT插件,插件安装过程也是一样,点击下一步就行了。

      3,对于VS和QT的安装顺序,没有严格的要求,并没有谁先谁后,这里我是之前已经安装好了VS2008中文版的。

     (三)安装好VS2008和QT相关软件之后,测试安装是否成功?

      第一步:启动VS2008,会发现VS2008的菜单栏出现Qt这个菜单

     

      第二步:单击VS2008的Qt菜单

     

      第三步:打开Qt Option可以看到Qt的Version已经被自动识别好(并非像老版本需要手动去设置) 

     第四步:打开VS2008,新建一个Qt项目

 

第五步:编译并运行MyApp项目,这里先不用(Qt的UI设计器,下面章节再进行介绍)设计,默认编译运行就行

生成的项目目录结构图:

运行成功截图如下:

总结:虽然在软件开发中,建议老版本的Qt稳定些,还有最好用英文版的VS2008,主要考虑稳定性,不过这里考虑到编译和设置旧版本的Qt实在繁琐耗时,并且弄了半天还是编译不通过,只好用新版本的Qt,这里还算顺利,没有出现什么错误,希望给新手一点帮助。

posted @ 2012-03-28 23:11 多彩人生 阅读(11720) | 评论 (1)编辑 收藏

C++中operator的另一种用法

http://www.joyloft.net/?p=484

几乎所有的C++教材上都讲了operator在C++中是重载操作符的关键字,但是恕我学业不精,昨天研究C++的语法文件时,才发现这个关键字还可以用来定义隐式的类型转换。

参见如下代码,类A在需要的时候可以自动的转换成bool形。

  1. class A
  2. {
  3. ??? public:
  4. ????? operator bool(void)
  5. ????? {
  6. ????????? return b;
  7. ????? }
  8. ??? private:
  9. ????? bool b;
  10. };
  11.  
  12. void main(void)
  13. {
  14. ??? A a;
  15. ??? bool b;
  16. ??? if(a)
  17. ??? {
  18. ??????? b = ! a;
  19. ??? }
  20. }

Post a comment 我有话说Trackback URI 引用路径(Trackback URI)

XML 订阅本站

本文 (链接) 由 Zenzen发表于 星期三, 八月 1st, 2007 4:09 PM,属于以下分类 编程开发.



Comments (3) left to “C++中operator的另一种用法”

  1. 夜弓 wrote:

    隐式转换有两个办法嘛
    一个就是上面说的operator type_name()
    另外一个是非explict的单参构造函数
    不过依赖隐式转换很容易出问题,而且很难调试
    恐怕只有自己写东西玩,和库作者才会用到

    Posted on 04-Aug-07 at 6:41 pm | Permalink

  2. 夜弓 wrote:

    补充一句
    其实上面这样定义出来的还是叫做重载操作符
    应该是,类型转换操作符
    就像C里面常见的(char)iValue一样。
    不过也可以用来进行隐式转换。

    Posted on 04-Aug-07 at 10:59 pm | Permalink

  3. 小彬 wrote:

    隐式类型转换可以使用构造函数以及但参数的构造函数
    class type
    {
    int a;
    public:
    type (int b) {
    a = b;
    }
    };

    main ()
    {
    type c = 123; //在此调用的是type的构造函数,自动转换类型。不过只有在初始化对象时才可以
    }
    在函数调用中也行

    void fun(type a)
    {

    }

    main ()
    {
    fun (123); //并没有错误,不过一个前提是函数的形参必须是传值调用而不能引用,并且没有参数为int类型的重载函数,否则会调用参数为int的函数(涉及到候选函数问题)
    }

    顺便说一下,你的主页很有意思

posted @ 2012-03-22 20:45 多彩人生 阅读(562) | 评论 (0)编辑 收藏

log4cpp

以下是个人理解,完善中.

三个组件: appender, layout, category
     category: 它应该是appender的集合器,就好像插线板,可以接多个电器,并将电流传给各个电器
     appender: 指定了个输出目的地,如FileAppender输出到文件, OstreamAppender输出到流。
                     通过成员函数setLayout指定输出格式
     layout: 就是输出格式

相关资料:
http://www.ibm.com/developerworks/cn/linux/l-log4cpp/

posted @ 2012-03-22 10:52 多彩人生 阅读(257) | 评论 (0)编辑 收藏

好的产品源于构建过程吗

原文名为:品质在于构建过程吗, 出自:http://coolshell.cn/articles/5625.html

一个好的产品源于一个好的想法,把想法转为现实的过程为构建过程

构建过程影响的只是“想法到现实”的难易程度,当一个构建过程实现出来的不是你心中的产品,你一定会寻找新的构建过程

===============================================

今天在微博上看到几位敏捷爱好者探讨敏捷测试和质量保证问题,我忍不住也加入了讨论:

Z先生原帖:我刚才看到一个大会演讲稿,谈到敏捷测试六大指导原则:1.仅靠测试人员不可能获得高质量的软件,质量是整个研发团队的责任;2. 场景是不可穷举的,测试活动必须是风险驱动的,关注于高风险的场景;3.分层自动化测试是唯一出路;4.在正确的位置进行恰当的测试是自动化的关键;【待续】

S先生回复:品质在于构建过程。检验贯穿构建过程,提供及时反馈。

我回复:什么样的构建过程才能出Unix这样的品质呢?迭代?快速反馈?TDD?

S先生回复:据说stroustrup听到重构时的反应是,我们从七十年代就这样做了。推荐《UNIX编程环境》,了解大师的编程方式。

我回复:您偷换了概念。不能说大师用了重构,C++和UNIX的品质就是靠重构或某种构建过程得来的。厨师做菜用到了勺子,不等于菜好吃是因为勺子。

S先生回复:我没有概念。我们看到一个果,就问因是什么。其实是泛因果,无因果,一切是机缘凑巧。

我回复:“品质在于构建过程”难道不是一个明白的因果描述吗?

S先生回复:品质在于构建的人。我说话时没因果,你看到了因果。

我回复:欢迎敏捷爱好者围观!

很高兴几个回合讨论下来S先生修正了先前“品质在于构建过程”的观点。什么重构、TDD、迭代、快速反馈等等构建过程都不是Unix品质的核心要素。我不但不认同“品质在于构建过程”、“测试是最好的设计方法”这类机械式的观点,而且也不满意把软件优劣归结于“人是根本”的简单回答。我们需要探索一个既非机械式,也非简单地归结为某种理念的答案。

像Unix这样优秀的软件,真正的核心要素到底是什么呢?我的答案是:模型,即人心中的软件。在看得见、摸得着之前,Unix的品质就已经存在于设计者的心中了,他们不会在Unix诞生后惊讶:“哇,Unix的稳定性这么好,7×24小时运行,从来不蓝屏”。模型一定是设计者心中最美的东西,为什么我们阅读操作系统源代码会像进入迷宫一般理不清头绪,而作者自己却觉得头头是道呢?因为作者早已“胸有成竹”,我们以为他几十万行代码敲很辛苦,实际上在他自己看来是按部就班一步步向目标靠近。

模型是软件的灵魂,存在于设计者的心中,而软件的构建过程正是心中的世界向现实世界逐渐投影。模型可以是完美的,而现实却非完美,或许有时候我们很幸运地到达了,或许有时候我们不得不向现实妥协,改变心中的世界。试图制造灯泡的爱迪生可能会一时找不到熔点极高的发光金属而止步不前,企图制造永动机的人则根本无法实现。在不完美的现实中,我们明明想的是a+b,却敲成了a-b;我们以为某个API可以很快返回,没想到却等了5秒钟,为了不阻塞用户不得不改成了异步。Review、测试等构建过程在一定程度上弥补了现实的不完美,并对模型给予了反馈,但它却无法决定软件的特质。如果设计者心中没有Unix,即使每个实现环节都层层检验,拥有光速般的反馈,他有怎么能构建出Unix呢?Windows NT内核和Windows 3.1内核的品质差别不在于微软采用了两种不同的构建过程,而在于它们采用了不同的内核模型。灵魂与躯体的差别就在于此!虽然对于普通的软件开发通常有不少成熟的模型供选择,并不需要总是创造自己的模型,但理解模型间的差异,并在设计时选用恰当的模型仍然比采用某种构建过程更加重要。服务器架构采用Nginx似的异步IO模型,还是采用Apache似的每个请求一个线程的模型远比开发是否采用了TDD更为重要。

模型的产生是柔性的,主要源于灵感;过程的执行是刚性的,主要源于逻辑。苹果砸在牛顿的脑袋上能砸出万有引力模型,砸在我们脑袋上却只是“哎呦”一声;但一个苹果3元钱,两个苹果2*3=6元钱却在牛顿和我们面前是平等的。迷信灵感和迷信逻辑是两个错误的极端,孔子讲“天下国家可均也,爵禄可辞也,白刃可蹈也,中庸不可能也”,任何一项技能的高级阶段都是关于“度”的艺术。如同光具有波粒二象性,软件开发也具有艺术创作和工业生产的二象性,它包含了柔性的设计和刚性的过程。越是不成熟的前沿领域越表现出柔性特征;越是成熟的一般领域越表现出工业生产的特征。因此,一个以新产品为主的创业型公司应当更注重设计,更需要画家、诗人般的创造型人才;而业务成熟产品稳定的大公司应当更注重过程,更需要踏踏实实的生产线工人似的人才。但在当今这个瞬息万变的信息时代,即使是世界500强的大公司也越来越不稳定,越来越需要创新才能适应,所以即使大公司也不可忽视软件开发的柔性特征。同时,我们也不能迷信模型,过程同样可以成为企业的核心竞争力,比如:富士康。虚虚实实,实实虚虚,其妙无穷。老外做Nike品牌(虚),我们做代工生产(实),高额利润被老外拿走了;我们经营航空公司(虚),老外生产波音飞机(实)高价卖给我们,高额利润又被老外拿走了。靠虚取胜还是靠实取胜?这是个问题^_^

或许我对于模型柔性的描述不太让人满意,人们多习惯于有章可循的感觉,即便不是死板的知识,起码要找个“在某某思想的指导下”才觉得心里有着落。或许还有人说,模型的确重要,那么我们能不能有一个过程、模式或套路来推导出模型呢?比如,现在非常流行的从用户需求出发的分析模式,即“分析需求,抽象出共性,共性是本质的,本质是稳定的”,这类模式的特点符合人们希望找到套路的心理,一看就明白,容易操作,有成就感。我不否认这类模式的确可以得出可用的软件设计,沿用成熟的模型也未尝不可。但我们应该明白,心中的世界远比现实的世界更广大更美妙。世界是多元的,用户需求、成熟模型等直接可见的东西只代表了某几个维度的视图,设计者心中应当有更多的维度!用户需要一个文本编辑器,是设计者心中的世界决定了他交出的作品是Vi,还是Emacs,亦或是Notepad。亨利·福特说:“如果你问用户需要什么,他会告诉你一匹更快的马”。汽车源于福特心中的世界,这是一个比只有马的世界更多彩的世界。乔布斯是一个不重视市场调研的人,iPod,iPhone,iPad都不是发个问卷,做个市场调查看看用户需要什么的结果。Apple是乔布斯心中的世界在现实中的投影!所以,请打破“从用户需求出发”,“从模式出发”的迷信,释放你的想象力,让自己心中的世界去包容现实的世界吧!

每个人心中都有一个属于自己的世界,牛顿运动定律是牛顿心中的世界,相对论是爱因斯坦心中的世界。哪一个才是本来的世界呢?有没有本来的世界呢?本来的世界是什么样子呢?… 老子给我们启示“道可道,非常道”,说得清,道得明,想得到的都不是永恒的真理,所以真理不可言说,对真理的探索永远没有止境……

posted @ 2012-03-14 19:47 多彩人生 阅读(162) | 评论 (0)编辑 收藏

vs2008 编译 log4cpp 报错解决方案

1. log4cpp1.0仅提供了vc6的工程文件,使用vs2008(VS2005)打开工程并进行转换

2. 直接编译log4cppDLL, 提示Custom Build Step时出现错误:

因为log4cpp在生成NTEventLogAppender.dll时,需要连接NTEventLogCategories.mc文件。 所以,项目设置了自定义的生成步骤去生成NTEventLogAppender.dll。但从vc6的工程文件转换时,这些步骤却没有正确的转换过来。

3. 重新填写Custom Build Step项:(右键->工程属性->选择自定义生成步骤
if not exist $(OutDir) md $(OutDir)
"mc.exe" -h $(OutDir) -r $(OutDir) $(SolutionDir)NTEventLogCategories.mc
"RC.exe" -r -fo $(OutDir)\$(InputName).res $(ProjectDir)\$(InputName).rc
"link.exe" /MACHINE:IX86 -dll -noentry -out:$(OutDir)\NTEventLogAppender.dll $(OutDir)\$(InputName).res

4. 在(右键->工程属性->选择自定义生成步骤)Outputs填写:$(OutDir)\NTEventLogAppender.dll

5. 继续编译, 再次报错, 连接失败, 找不到符号

因为工程没有包含源文件: FactoryParams.cpp & Localtime.cpp

6. 手动添加上述两个文件到工程, 重新编译通过, 并生成log4cpp.dll


posted @ 2012-03-10 13:16 多彩人生 阅读(683) | 评论 (0)编辑 收藏

基于LGPL开源项目 Log4cpp安装与使用

     摘要: 【IT168 专稿】Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能。使用log4cpp,可以很便利地将日志或者跟踪调试信息写入字符流、内存字符串队列、文件、回滚文件、调试器、Windows日志、syslog和远程syslog服务器中。   1、Log4cpp简介   Log4cpp是个基于LGPL的开源项目,移植自Java的日志处理跟踪项目log4j,并保...  阅读全文

posted @ 2012-03-10 11:52 多彩人生 阅读(3038) | 评论 (0)编辑 收藏

数据库

sql, nosql, 内存数据库


关系数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示。关系模型是由埃德加·科德于1970年首先提出的,并配合“科德十二定律”。现如今虽然对此模型有一些批评意见,但它还是数据存储的传统标准。标准数据查询语言SQL就是一种基于关系数据库的语言,这种语言执行对关系数据库中数据的检索和操作。 关系模型由关系数据结构、关系操作集合、关系完整性约束三部分组成

实体关系模型

  实体关系模型(Entity-Relationship Model),简称E-R Model是陈品山(Peter P.S Chen)博士于1976年提出的一套数据库的设计工具,他运用真实世界中事物与关系的观念,来解释数据库中的抽象的数据架构。实体关系模型利用图形的方式(实体-关系图(Entity-Relationship Diagram))来表示数据库的概念设计,有助于设计过程中的构思及沟通讨论。
  关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织。当前主流的关系型数据库有Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL等。

关系操作
  关系模块中常用的操作包括:
  数据查询
  选择 投影 连接 并 交 差 除 数据操作 增加 删除 修改 更新
///////////////////////////////////

posted @ 2012-03-09 16:58 多彩人生 阅读(194) | 评论 (0)编辑 收藏

VS中的路径宏

说明

$(RemoteMachine)

设置为“调试”属性页上“远程计算机”属性的值。有关更多信息,请参见更改用于 C/C++ 调试配置的项目设置。

$(References)

以分号分隔的引用列表被添加到项目中。

$(ConfigurationName)

当前项目配置的名称(例如“Debug”)。

$(PlatformName)

当前项目平台的名称(例如“Win32”)。

$(Inherit)

指定在由项目生成系统所撰写的命令行中,继承的属性出现的顺序。默认情况下,继承的属性出现在当前属性的末尾。

$(NoInherit)

使任何将被继承的属性不被继承。若还要避免同级级别的计算,请使用 $(StopEvaluating)。使用 $(NoInherit)会导致对于同一属性忽略任何出现的 $(Inherit)

$(StopEvaluating)

立即停止计算链中宏的计算。出现在 $(StopEvaluating) 之后的任何值将不出现在宏的计算值中。如果$(StopEvaluating) 在 $(Inherit) 之前,计算链中当前位置的继承值将不会连接到宏值。$(StopEvaluating)是 $(NoInherit) 的功能超集。

$(ParentName)

包含此项目项的项的名称。该名称将是父文件夹名称或项目名称。

$(RootNameSpace)

包含应用程序的命名空间(如果有)。

$(IntDir)

为中间文件指定的相对于项目目录的目录路径。它解析为“中间目录”属性的值。

$(OutDir)

输出文件目录的路径,相对于项目目录。这解析为“输出目录”属性的值。

$(DevEnvDir)

Visual Studio .NET 的安装目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。

$(InputDir)

输入文件的目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。如果该项目是输入,则此宏等效于 $(ProjectDir)。

$(InputPath)

输入文件的绝对路径名(定义形式:驱动器 + 路径 + 基本名称 + 文件扩展名)。如果该项目是输入,则此宏等效于 $(ProjectPath)。

$(InputName)

输入文件的基本名称。如果该项目是输入,则此宏等效于 $(ProjectName)。

$(InputFileName)

输入文件的文件名(定义为基本名称 + 文件扩展名)。如果该项目是输入,则此宏等效于 $(ProjectFileName)。

$(InputExt)

输入文件的文件扩展名。它在文件扩展名的前面包括“.”。如果该项目是输入,则此宏等效于 $(ProjectExt)。

$(ProjectDir)

项目的目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。

$(ProjectPath)

项目的绝对路径名(定义形式:驱动器 + 路径 + 基本名称 + 文件扩展名)。

$(ProjectName)

项目的基本名称。

$(ProjectFileName)

项目的文件名(定义为基本名称 + 文件扩展名)。

$(ProjectExt)

项目的文件扩展名。它在文件扩展名的前面包括“.”。

$(SolutionDir)

解决方案的目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。

$(SolutionPath)

解决方案的绝对路径名(定义形式:驱动器 + 路径 + 基本名称 + 文件扩展名)。

$(SolutionName)

解决方案的基本名称。

$(SolutionFileName)

解决方案的文件名(定义为基本名称 + 文件扩展名)。

$(SolutionExt)

解决方案的文件扩展名。它在文件扩展名的前面包括“.”。

$(TargetDir)

生成的主输出文件的目录(定义形式:驱动器 + 路径);包括尾部的反斜杠“\”。

$(TargetPath)

生成的主输出文件的绝对路径名(定义形式:驱动器 + 路径 + 基本名称 + 文件扩展名)。

$(TargetName)

生成的主输出文件的基本名称。

$(TargetFileName)

生成的主输出文件的文件名(定义为基本名称 + 文件扩展名)。

$(TargetExt)

生成的主输出文件的文件扩展名。它在文件扩展名的前面包括“.”。

$(VSInstallDir)

安装 Visual Studio .NET 的目录。

$(VCInstallDir)

安装 Visual C++ .NET 的目录。

$(FrameworkDir)

安装 .NET Framework 的目录。

$(FrameworkVersion)

Visual Studio 使用的 .NET Framework 版本。与 $(FrameworkDir) 相结合,就是 Visual Studio 使用的 .NET Framework 版本的完整路径。

$(FrameworkSDKDir)

安装 .NET Framework SDK 的目录。.NET Framework SDK 可作为 Visual Studio .NET 的一部分安装,也可单独安装。

$(WebDeployPath)

从 Web 部署根到项目输出所属于的位置的相对路径。返回与 RelativePath 相同的值。

$(WebDeployRoot)

指向 <localhost> 位置的绝对路径。例如,c:\inetpub\wwwroot。

$(SafeParentName)

有效名称格式的直接父级的名称。例如,窗体是 .resx 文件的父级。

$(SafeInputName)

作为有效类名的文件的名称,但不包括文件扩展名。

$(SafeRootNamespace)

项目向导将在其中添加代码的命名空间名称。此命名空间名称将只包含在有效的 C++ 标识符中允许的字符。

$(FxCopDir)

fxcop.cmd 文件的路径。fxcop.cmd 文件不和所有的 Visual C++ 版本一起安装。

posted @ 2012-03-08 11:34 多彩人生 阅读(2224) | 评论 (0)编辑 收藏

被忽视的

被忽视的,只到用时才注意到
1
头文件中用using namespace XXX;会使所有包含该头文件的文件都被包含在名词空间XXX中。
在头文件中应该全部用XXX::。

posted @ 2012-03-08 11:19 多彩人生 阅读(216) | 评论 (0)编辑 收藏

仅列出标题
共25页: First 17 18 19 20 21 22 23 24 25 

导航

统计

常用链接

留言簿(3)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜