• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            asm, c, c++ are my all
            -- Core In Computer
            posts - 139,  comments - 123,  trackbacks - 0

            轉(zhuǎn)載自天蝎之巢:Windows編程中SetViewportOrg與SetWindowOrg的理解
            ????????????????????????????????????????
            最近突然又很有激情的開始看Jeff Prosise的那本"Programming Windows with MFC, 2 ed."。盡管是英文版的,但是感覺(jué)這本書上手比喉結(jié)的那本所謂的 深入淺出MFC 要容易理解的多。候同學(xué)給人一種故弄玄虛故作深沉的感覺(jué),而Jeff Prosise的這本書才真正的稱得上是深入淺出。

            盡管如此,其中有關(guān)GDI繪圖中的坐標(biāo)映射部分還是有一個(gè)問(wèn)題沒(méi)有搞清楚,那就是SetWindowOrg和SetViewportOrg這兩個(gè)函數(shù)到底應(yīng)該如何理解。潘愛(ài)民翻譯的那本VC內(nèi)幕沒(méi)有講清楚;Jeff Prosise的這本書沒(méi)有講清楚;MSDN上的東西看的也是一頭霧水;Charles Petzold的那本書還沒(méi)有來(lái)得及看。因?yàn)檫@個(gè)問(wèn)題,昨天晚上是帶著遺憾的困惑入睡的。

            總的來(lái)說(shuō),我對(duì)這兩個(gè)函數(shù)的理解導(dǎo)致的結(jié)果是與實(shí)際程序運(yùn)行的結(jié)果截然相反。依據(jù)MSDN上的解釋,有一個(gè)很嚴(yán)重的問(wèn)題沒(méi)有闡述清楚,那就是:所謂的SetWindowOrg(x, y)函數(shù),到底是表示set window origin to (x, y)還是set window origin as (x, y);to和as在執(zhí)行的時(shí)候,其操作的效果是截然相反的。

            set window origin to (x, y)表示將坐標(biāo)原點(diǎn)設(shè)置到(x, y);即以(x, y)作為坐標(biāo)原點(diǎn),此時(shí)原點(diǎn)坐標(biāo)不再為(0, 0);
            set window origin as (x, y)表示將原來(lái)的原點(diǎn)(0, 0)的坐標(biāo)改為(x, y);即將所有點(diǎn)的坐標(biāo)增加(+x, +y);

            現(xiàn)在我的理解是:應(yīng)該是 set window origin to (x, y)。這種理解基于以下幾個(gè)前提:
            1. 所有繪圖語(yǔ)句中給出的坐標(biāo),全部是邏輯坐標(biāo),即在 window 中的坐標(biāo)(相對(duì)于viewport所表示的設(shè)備坐標(biāo)而言);
            2. 所有用戶能看到的點(diǎn),其設(shè)備坐標(biāo)一定是位于(0, 0)和(1024, 768)范圍內(nèi);(假設(shè)顯示器為輸出設(shè)備,采用MM_TEXT映射方式,且屏幕分辨率為1024*768);
            3. 所謂“(0,0)就原點(diǎn),原點(diǎn)的坐標(biāo)一定就是(0,0)”這種理解,是錯(cuò)誤的;
            4. Viewport中的坐標(biāo)表示設(shè)備坐標(biāo);Window中的坐標(biāo)表示邏輯坐標(biāo);
            5. 當(dāng)在邏輯坐標(biāo)中指定新的原點(diǎn)后,在執(zhí)行映射時(shí),設(shè)備坐標(biāo)的原點(diǎn)一定要與邏輯坐標(biāo)的新原點(diǎn)重合;反過(guò)來(lái)也是一樣,即兩個(gè)坐標(biāo)系的原點(diǎn)一定要重合。

            下面舉例說(shuō)明:(MM_TEXT映射模式)

            (1)
            CRect rect(0, 0, 200, 200);
            dc.rectangle(rect);
            上面的語(yǔ)句在屏幕的最左上角繪制一個(gè)正方形;(因?yàn)榇藭r(shí)邏輯坐標(biāo)與設(shè)備坐標(biāo)沒(méi)有偏移)

            (2)
            dc.SetViewportOrg(100, 100);
            CRect rect(0, 0, 200, 200);
            dc.rectangle(rect);
            將設(shè)備坐標(biāo)的原點(diǎn)設(shè)置到(100, 100);即設(shè)備坐標(biāo)的原點(diǎn)不在(0, 0)處,而是在(100, 100)處;此時(shí)若執(zhí)行映射的話,邏輯坐標(biāo)的原點(diǎn)(0, 0)需要與設(shè)備坐標(biāo)的原點(diǎn)(100, 100)重合(參考前提5);那么此時(shí)繪制的矩形(0, 0, 200, 200)的坐標(biāo)(為邏輯坐標(biāo),參考前提1)在設(shè)備坐標(biāo)中就會(huì)映射為(100, 100, 300, 300),最終我們?cè)陲@示器上看到的會(huì)是一個(gè)向右下方偏移(100, 100)的一個(gè)邊長(zhǎng)為200的正方形(用戶看到的點(diǎn)是在設(shè)備坐標(biāo)中的,參考前提2)

            (3)
            dc.SetWindowOrg(100, 100);
            CRect rect(0, 0, 200, 200);
            dc.rectangle(rect);
            將邏輯坐標(biāo)的原點(diǎn)設(shè)置到(100, 100);即邏輯坐標(biāo)的原點(diǎn)不在(0, 0)處,而是在(100, 100)處;此時(shí)若執(zhí)行映射的話,設(shè)備坐標(biāo)的原點(diǎn)(0, 0)需要與邏輯坐標(biāo)的原點(diǎn)(100, 100)重合(參考前提5);那么此時(shí)繪制的矩形(0, 0, 200, 200)的坐標(biāo)(為邏輯坐標(biāo),參考前提1)在設(shè)備坐標(biāo)中就會(huì)映射為(-100, -100, 100, 100),最終我們?cè)陲@示器上看到的會(huì)是一個(gè)只有1/4個(gè)大小的矩形的一部分(事實(shí)上相當(dāng)于向左上方偏移(100, 100)的一個(gè)邊長(zhǎng)為200的正方形。注意:用戶看到的點(diǎn)是在設(shè)備坐標(biāo)中的,參考前提2)

            posted @ 2006-07-11 04:11 Jerry Cat 閱讀(440) | 評(píng)論 (0)編輯 收藏
            替意大利高興, 為法國(guó)隊(duì)惋惜!
            posted @ 2006-07-10 05:38 Jerry Cat 閱讀(502) | 評(píng)論 (4)編輯 收藏
            /********************************************\
            |????歡迎轉(zhuǎn)載, 但請(qǐng)保留作者姓名和原文鏈接, 祝您進(jìn)步并共勉!???? |
            \********************************************/


            讀VC++內(nèi)幕之體悟 - 05

            作者: Jerry Cat
            時(shí)間: 2006/07/09
            鏈接: http://www.shnenglu.com/jerysun0818/archive/2006/07/09/9612.html


            5.?? ActiveX控件不像普通控件那樣,發(fā)送以WM_打頭的通知消息給它的包容器,而是“激發(fā)事件”。事件有一個(gè)符號(hào)化的名字及一組任意次序的參數(shù),它實(shí)際上是有控件調(diào)用的包容器函數(shù)。對(duì)于客戶類來(lái)說(shuō),事件與控件的通知消息是一樣的。
            posted @ 2006-07-09 19:59 Jerry Cat 閱讀(484) | 評(píng)論 (0)編輯 收藏

            /********************************************\
            |????歡迎轉(zhuǎn)載, 但請(qǐng)保留作者姓名和原文鏈接, 祝您進(jìn)步并共勉!???? |
            \********************************************/


            美國(guó)人掛在嘴邊的句子

            作者: Jerry Cat
            時(shí)間: 2006/07/09
            鏈接:
            http://www.shnenglu.com/jerysun0818/archive/2006/07/09/9611.html

            1-----You can't argue with success

            Though you may tell someone they are doing something in a wrong way, you have to stop criticizing them if their method works.


            2-----Nothing succeeds like success

            Like money in a savings account, success seems to compound itself. A person who has a small success expects it to be followed by a bigger one.


            3-----The end justifies the means

            It does not matter how you succeed. Any method is all right if it works for you. This proverb is not always accepted. Often one hears the opposite, " the end doesn't justifies the means."


            4-----If you can't beat them, join them

            If you cannot compete successfully with a person or a group, stop competing and go join them. Then you can share in their success.


            5-----Always a day late and a dollar short

            A criticism of a person who never succeeds. The failures may not be drastic but the pattern of small failures is annoying to others, especially in two areas that Americans value as highly as time and money.


            6-----One thing at a time

            Concentration leads to success. The person who tires to do too many things at once may fail at all of them.


            7-----We'll cross that bridge when we come to it

            We will not discuss or worry about a future problem. If and when the problem becomes urgent, we will deal with it.


            8-----Don't put the cart before the hourse

            Do things in a sensible order. For example, do something to impress your boss before you ask for a raise in pay. Don't ask for the raise first.


            9-----All's fair in love and war

            Do not trust a rival or an enemy at all. His or her desire to succeed will overrule everything else. Such a people may lie, cheat, attack or do many other things far more terrible than he or she would normally do.


            10-----When in Rome do as the romans do

            Flexibility leads to success in unfamiliar circumstances. People may changes their normal way of doing things in order to fit in better with those they are visiting.


            11------Easy does it

            Some things require gentleness for success. One should not push too hard. Force may cause damage

            12-----The bigger they are, the harder they fall

            Do not be discouraged by the size of your problem or the fame of your competitor. (the saying is traced to a boxer preparing to fight an opponent much larger than he was.)


            13-----All is well that ends well

            If we can come to a successful conclusion, let us forget about the pain and mistakes along the way.


            14-----Go for it

            Go ahead and try to achieve your goal. Don't worry about failing. Similar to this proverb--God provides food to every bird, but he won't cast to its nest, you got to earn it.


            15-----Every little bit helps

            If someone apologizes for giving only a small gift, the recipient may encourage the giver by quoting this proverb. This is especially true if there is a huge job to do or a huge amount of money to be raised from many people.


            16-----Look before you leap

            Don't jump into a situation carelessly. You may land in difficulty.


            17-----All that glitters is not gold

            Do not be fooled by worthless things that seem valuable or look attractive.

            "Fool's gold " is the popular name for a kind of stone that glitters like gold but contains no gold at all.


            18------Curiosity killed the cat

            Do not ask too many questions or become too curious about things. You may get yourself into trouble like a cat that does not see the danger in a new situation.


            19-----Don't put all your eggs in one basket

            Do not risk everything in one place or on one project. Divide your sources that one failure will not ruin you. Similar to this proverb---Do not use both feet to test the depth of the river.


            20-----Don't bite off more than you can chew

            Do not attempt something too large for you to handle.


            21-----Too good to be ture

            This is often used to warn about advertising. An offer looks good but turns out to be misleading.


            22-----Flattery will get you nowhere

            If flattery (insincere praise) is recognized, it will not succeed. One sometimes hears the opposite, Flattery will get you everywhere.


            23-----There is no such thing as a free lunch

            If someone you do not know offers you a free lunch or other gift, watch out. The gift may be a method of getting something from you.


            24------Pride goes before a fall

            Do not be over-confident and careless. Your circumstances may change quickly and the emptiness of your bragging will be exposed.


            25------Better safe than sorry

            It is better not to take a risk than to take a risk foolishly.


            26-----Winning isn't everything

            One may enjoy the process of playing a game whether one wins or not. This traditional proverb is now often heard in the opposite form, Winning isn't everything. It's the only thing!


            27------Time will tell

            Wait and see how something will work out. Don't trust a person or thing too much right now.


            28-----The burned child shuns fire

            Some of life's lessons are learned the hard way. The person who has had to pay for a mistake will be careful not to make that mistake again.


            29-----There are other fish in the sea

            There are opportunities! For example, this may be used to encourage someone who has just broken off a relationship with a sweetheart.


            30-----Don't count your chickens before they are hatched

            Do not become too confident of success before you can see that progress is happening.


            31-----Rome wasn't built in a day

            Do not be discouraged if your goal still seems far away. On a big project, success takes time!


            32-----There is more here than meets the eye

            Be careful. People are hiding something in order to protect themselves or take advantage of you.


            33-----The customer is always right

            Businesses instruct their clerks not to do anything that might threaten a customer's self-esteem, no matter how unreasonable the customer is. Any complaint of any customer must be carefully and politely heard by any employee. The customer must not be made to feel ignorant.


            34-----Be true to yourself

            Do not compromise yourself or your beliefs in order to please other people or fit in with a system. Know who you are. Let other people know what you stand for. Do not give in to pressure to conform or to do things you do not agree with.


            35-----Once bitten, twice shy

            This may be used to explain the behavior of a person who is overly cautious about something. The wise person makes mistakes but does not usually make the same mistake twice.


            36-----It isn't over till the fat lady sings

            I refuse to admit defeat yet. Though right now it looks like I may fall, there is still time for things to change. (The "fat lady" is an insulting reference to an opera soloist, opera often end with a female solo.)


            37-----To each his own

            Each individual should be allowed to have his or her own preferences. people will naturally choose different activities, goals, life-s, etc.


            38-----Looking out for number one

            Looking out for one's own personal welfare more than anything else. This is sometimes used to criticize a person who has abused or taken advantage of someone else, "All he was doing was looking out for number one." Or it may be used to defend himself or herself, "There is nothing wrong with what I did. I was just looking out for number one."


            39-----When the going gets tough, the tough get going

            When situation is difficult, only the determined people can handle it. They don't give up!


            40-----Times flies when you are having fun

            A day seems shot when it is full of enjoyable things but it seems like an eternity if one is idle or stuck with a boring job.


            41-----If it feels good, do it

            Live according to your desires at the moment. Forget about rules, regulations or consequences. Just have fun.


            42-----Live and let live

            Do not be judgmental. Do not try to control or punish other people.

            You live as you like and let others live as they like.

            43-----Variety is the spice of life

            Variety is what makes life pleasureable. Boredom is seen as a threat and monotony is the surest route to boredom.

            44------Money talks

            Wealth has influence. People who make big contributions to political candidates are "talking" to the candidates and expecting them to listen.

            45-----All work and no play makes Jack a dull boy

            This is used to criticize someone who takes work too seriously. It affirms that play is as an essential part of human life.


            46-----The more the merrier

            This is a way of welcoming someone to participate. It means, the bigger the group, the bigger the party.


            47------A bird in the hand is worth two in the bush

            A thing you already have is worth twice as much as a thing you might get in the future.


            48-----You can't have your cake and eat it too

            Make up your mind. Sometimes one must choose between two very desirable things, giving up one thing in order to enjoy the other.


            49-----There is more than one way to skin a cat

            Any of several methods may bring about the desired result. Each person may choose the method that best suits her. If one method does not work, choose a different one and try again.


            50-----One man's meat is another man's poison

            Since the same thing may affect different people in different ways, each person must choose the things that will work in his or her particular case.?

            51-----Love finds a way

            Love is considered one of the most powerful and determined forces in the world. Two people in love will "find a way" to get together.


            52-----Absence makes the heart grow fonder

            When lovers are separated, they may think about each other constantly. their love may deepen.


            53-----Out of sight, out of mind

            This is said of someone not considered important or worthy of loyalty. One forgets about that person as soon as he or she is out of sight.


            54------Love makes the world go around

            Love is the driving force in all of life. Love makes life worth living. If you understand love,you understand everything about life.


            55-----Marry in haste and repent at leisure

            Do not rush into any long-term commitment. In the past this meant, "take your time before you commit yourself to a marriage partner." Now it means, "Do not commit yourself to anyone you will be sorry." or it may mean, "Live with a person for a while before marrying him or her." It may also apply to any long-term partnership, such as a joint business venture.


            56------Talk is cheap

            Talking is not doing, It is easy to talk about a plan, but this gets little respect untill one takes a risk and puts the plan into action.


            57-----Love is blind

            When people are in love, they do not see each other's faults.


            58-----Time is money

            Time can be converted to money, that is, wages are often paid per hour of work. Managers want employees to do things quickly because "time is money." If employees waste time, the company loses money.


            59-----If you're so smart, why ain't you rich

            This question implies that intelligence, like time, can be converted into money. It is used to cut down an ordinary person (not a rich one) who has expressed an opinion as if it is the final word on the subject.


            60-----Beggars can't be choosers

            Beggars have to accept whatever they get. A poor person has very few choices in life. This harsh reply may be used if people complain about the size or quality of a gift.


            61-----The love of money is the root of all evil

            Greed will lead a person into many other evils such as cheating, oppression and violence. (one also hears, money is the root of all evil, which places the blame more on money than on greed.)


            62-----A fool and his money are soon parted

            Folly will always show up in the way a fool handles money. Wise people are the ones smart enough to guard money once they have it.


            63-----It isn't whether you win or lose, it's how you play the game

            Playing well and fairly is more important than succeeding. This saying is sometimes used to console someone who has lost a game. The ideas is that in spite of losing, one may still feel like a success if one has played as well as possible.


            64-----Money can't buy happiness

            There are some things money just can't buy. This reminds people that money is not an ultimate value although it often is treated as one. The saying may be used as a comment when a wealthy but lonely and wretched person commits suicide.


            65-----Nice guys finish last

            Success is valued more highly than kindness and politeness. If unkindness and impoliteness contribute to one's success, they are sometimes excused as "toughness" or "what it takes." This is more often applied to men than woman.


            66-----The one who dies with the most toys wins

            This recent, cynical saying makes fun of three common American desires-- competing, accumulating property, and having fun.


            67-----Just do it

            This proverb is actually a recently invented advertising slogan for the Nike Shoe company. It may also be the best three-word summary of American cultural values. It means, "quit being indecisive, Don't bother consulting a lot of people. Don't waste much times on planning. Just do it and do it now.


            68-----You only go around once in life

            Enjoy life, do what you want to do, experience everything you can.


            69-----Put your money where your mouth is

            Get serious about what you are saying. When you have spoken in favor of something, prove that you mean it by risking some money on it in a bet or an investment.


            70-----The best defense is a good offense

            Be pro-active and goal-oriented, not timid or conservative. Aim to conquer, not merely to protect yourself.


            71-----The road to hell is paved with good intentions

            Like talking, intending is not doing. Actions matter far more than intentions. Actions determine where a person ends up.


            72-----Never put off till tomorrow what you can do today

            Doing is better than waiting. If you wait, you might lose your opportunity


            73-----Action speak louder than words

            To know people's hearts, pay more attention to what they do than what they say.


            74-----Idle hands are the devil's workshop

            When people have nothing constructive to do, they get into mischief. The child who is bored may pick up a crayon and color on the wall, something that would not happen if the child were happily occupied in some other activity.


            75-----You've got to take the bull by the horns

            Grab directly and fearlessly for the toughnest part of a problem. Don't look for an easy way out.


            76-----Money doesn't grow on trees

            You have to work for things. Success does not come on its own.


            77-----Easy come, easy go

            If you have received something without working for it, it may soon be gone. You will not be as careful with it as you will be with something you earned.


            78-----Too many cooks spoil the broth

            Individual action or action by the smallest group possible is better than consulting a lot of people. Too much consultation will waste time and create problems.


            79-----Stand on your own two feet

            Grow up; act like an adult. Don't ask me to do something for you. This may be said to a young or immature person who depends too much on others. It is like a cow kicking a grown calf that wants to suckle.


            80------If you want something done right, do it yourself

            This discourages people from trusting anyone except themselves. It maybe said to someone who ask another person to do a job for him/her and then complains about it was done.


            81------Necessity is the mother of invention

            When a person really needs something, he or she figures out some new way to get it. This creative initiative to change one's situation is considered much better than giving up and accepting things as they are.


            82------First come, first served.

            This saying is used when there is a limited supply of something such as tickets to an event or food at a picnic. The idea is that no matter what your status, if you want some of what is being given away or sold, you must present yourself in person and in good time.


            83-----No pain no gain

            one must put forth an effort in order to succeed. This saying comes from physical fitness instructors. They say that if you do not exercise hard enough to make your muscles hurt, the exercise is not doing you much good.


            84-----Give him an inch and he'll take a mile

            Be careful of presumptuous people who take more initiative than they should. If you do someone a small favor or delegate a little permission or a little power, he or she may take advantage of you.


            85-----If it isn't broke, don't fix it

            Do not bother trying to improve something if it is already working satisfactorily. That is a waste of time and you run the risk of breaking the thing while you are trying to improve it.


            86-----There is no harm in trying

            A person expects to be respected for making an effort even if it does not succeed.


            87-----The cure is worse than the disease

            While trying to solve one problem, we create an even bigger problem. We would have been better off if we had done nothing.


            88-----Count to ten before you lose your temper

            Do not instantly let your feelings control your actions. Slow down. Think before you react.


            89-----All things come to him who waits

            Sometimes patience is better than initiative.


            90-----There is many a slip between the cup and the lip

            This refers to a plan that has gone wrong. When one is drinking from a cup, one intends to get all the drink into the mouth, but this does not always happen. The plan is good but it can still fail.


            91-----Boys will be boys

            People will act according to their nature, including some mischief. This is sometimes used to describe irresponsible but not too seriously wrong behavior by men. In other words, grown men will sometimes act like little boys.


            92------One bad apple can spoil the whole barrel

            Do not associate with bad people. They may spoil you as a rotting apple spoils the apples next to it in the barrel.


            93-----Better the devil you know than the devil you don't

            People are generally not trustworthy. It is therefore better to deal with a familiar person or situation than an unknown one. That way you know what to watch out for and you can protect yourself better.

            94-----Nobody is perfect

            Everyone has shortcomings. This is used as an excuse for a minor Mistake that has been made.


            95------The grass is always greener on the other side of the fence

            People are never satisfied with what they have. They always want what someone else has.


            96-----A man is only as old as he feels

            A person's energy level is more important than age.


            97-----A man's home is his castle

            At home a man is like a king, completely free to do as he wishes.


            98-----Clothes make the man

            The way a man dresses will affect the way he sees himself and the way other people see him. The implication is that if you want to succeed, dress for success.


            99-----Two heads are better than one

            Two people are more likely to succeed than one working or thinking alone. It is better to consult than to act alone.


            100-----Beauty is only skin deep

            One should admire a person, particularly a woman, for her deep, inner character and not simply for her superficial beauty.


            101-----Many hands make light work

            Cooperation makes a job much easier.


            102-----There is safety in numbers

            Do not take large risks all by yourself. Do not walk alone on a dangerous street at night.


            103-----Charity begins at home

            One should be kind to close relatives before doing good to the community in general.


            104-----There is no place like home

            Home is the best place in the world. The most relaxing and enjoyable place.


            105-----Silence is consent

            Do not stay silent when you see a problem or an injustice. Speak out against it. Say, "Enough is enough." or people will think you do not mind the situation.


            106-----What goes around comes around

            What you do to others, especially if it is bad, will eventually be done to you. As you seek your own success, do not treat other people badly. They may take revenge and spoil your success.


            107-----Honesty is the best policy

            When one is tempted to cheat, this proverb serves as a reminder of the importance of good character. Honesty brings trust and trust leads to success.


            108-----If the shoe fits, wear it

            If an accusation is true, accept the blame. This saying can also mean, " if a suitable opportunity comes to you, take it!"


            109-----You can lead a horse to water, but you can't make him drink

            Even when given an opportunity, some people will not use it. In that case the blame is all on him.


            110-----You made the bed, you lie in it

            You created a certain situation so you are now responsible to take the consequences.


            111-----The pot calling the kettle black

            Since the pot and the kettle are equally black from the cooking fire, the pot has not right to criticize the kettle. This might be used if someone known to be a gossip criticizes someone else for gossiping.


            112-----Don't get mad, get even

            When someone treats you badly, do not just get angry, express your anger in action.


            113-----Get a life

            Do not be so unreasonably critical about tiny things. Find something better to do with your time.


            114-----My country, right or wrong

            I am absolutely loyal to my country whether or not I agree with its policy in a certain area.


            115------There are two sides to everything

            Never assume that all the blame for a conflict lies on one side, especially if you have heard only one side of the story.


            116-----Forgive and forget

            Conflicts should be resolved and ended, not left alone to cause years of regret, bitterness and pain.


            117------Business and pleasure don't mix

            When you work, work. When you play, play. It is inefficient and therefore unwise to try to mix the two.


            118-----Let a sleeping dog lie

            Do not meddle in something that will cause you no trouble if you leave it alone. If you wake up the "dog," it may bite you.


            119------No man can serve two masters

            Divided loyalty will break down sooner or later.


            120-----Make it short and sweet

            Speak briefly and to the point. We don't have time for the details


            121-----What will be will be

            Some things cannot be changed or avoided.


            122-----A friend in need is a friend indeed

            My true friend is the one who show loyalty to me by helping me when I am in need.


            123-----People who live in glass house should not throw stones

            Do not attact anyone if you have no way to defend yourself when they attact you in the same way.

            124-----Opposites attract

            As positive and negative magnets attract each other, so people of very different types attract each other. For example, a quiet woman marries a very outgoing man. These differences have a mixed effect on the couple, partly making them interested in each other but also leading to miscommunication and conflict.


            125-----The early bird catches the worm

            Punctuality is important. If you want to succeed, arrive early, like the bird that hunts worms at dawn before they go into hiding for the day.


            126-----Blood is thicker than water

            Blood relationship is stronger than voluntarily chosen friendship. Brothers will stick up for each other against their own friends if they have to. This proverb is not quoted much anymore because kinship is not as highly valued as it used to be.


            127-----You can't teach an old dog new tricks

            Once habits are learned, it is very hard to change them.


            128-----To err is human

            It is normal for humans to make mistakes and it is godly (or God-like) to forgive them.


            129-----Haste makes waste

            Through acting quickly is generally a good thing, acting too quickly may cause troulbe. This proverb is used when someone has done a job carelessly and wrongly. For example, a carpenter in a hurry may cut a board too short and have to throw it away.


            130-----Make hay while the sun shines

            If you do not seize the opportunity, rain may come and spoil the hay before you get into the barn.


            131-----If you can't stand the heat, get out of the kitchen

            Withdraw from an activity if you don't like the conflict and criticism it brings. Let other people do it without you.


            132-----Everyone puts their pants on one leg at a time

            This is to tell us that we are all equal.


            133-----Life is a pie

            It's dished out in large and small pieces and when's gone, it's gone. If we ask for more than our share, we're just begging to be disappointed.


            134-----Making every minute count

            Doing something productive all the time, not letting any time "slip away."

            135-----A pen is mightier than the sword

            A conflict maybe resolved more deeply and effectively by writing the truth than by resorting to violence.


            136-----A new broom sweeps clean

            A new person in power will change many things and improve the situation. change is better than leaving things as they are.


            137-----Tomorrow is another day (or, Tomorrow is a new day.)

            No matter how bad things are right now, a person may hope for better prospects in the morning. New opportunities will come.


            138-----Opportunity only knocks once

            Opportunity is like an unexpected stranger passing by. It knocks on someone's door. If the person fails to answer the door, opportunity goes away and knocks on someone else's door. It does not return to the same person.


            139-----Business is business

            Do business with strangers as if they were brothers and with brothers as if they were strangers.


            140-----History repeats itself

            There are patterns in history. Nations rise and fall for similar reasons. Nations do not change their ways or learn from the mistakes of others. They repeat them.


            141-----People are people

            Their human nature is predictable. They respond to stimulus and incentives.


            142-----Keep your friends close, keep your enemies closer

            A man without enemy is a man without quality. Think not? Even Jesus Christ had many, many enemies.


            143-----Better late than never

            Though being on time is better than being late, doing something late is better than giving up or doing nothing.


            144-----Punish one, teach a hundred

            People problems sometimes must be dealt with harshly. When you make an example of someone, make sure that everyone knows what the lesson is.


            145-----Attitude is everything

            A pessimist sees a glass half-empty, An optimist sees it half-full.


            146-----Like father, like son

            A son will be like his father. This may be quoted whenever the son has done something that reminds people of the father. Whether it is good or bad.


            147-----When the cat's away the mice will play

            People will take advantage of a situation if they can. Employees will get lazy if the supervisor is not keeping an eye on them. A teenage son or daughter might hold a wild party at home during a weekend when the parents have gone out of town.


            148-----Praise when praise is due (sometimes even when it isn't)

            Do not criticise beyond necessity and seldom in public. And always precede criticism with a few words of praise.


            149-----Turnabout is fair play

            If a person is taking advantage of someone else, the situation may change. The one on top may end up on the bottom. Then the one who has turned the tables will say, "I am only doing to you what you did to me.


            150-----Here today, gone tomorrow

            Things may change quickly. This is said as a criticism of a person who changes quickly for no good reason. It may also be said of a thing or situation which does not last. Change is not good when it indicates unreliability.

            posted @ 2006-07-09 19:51 Jerry Cat 閱讀(1118) | 評(píng)論 (1)編輯 收藏

            C/C+語(yǔ)言struct深層探索

            出處:PConline

            1. struct的巨大作用
              面對(duì)一個(gè)人的大型C/C++程序時(shí),只看其對(duì)struct的使用情況我們就可以對(duì)其編寫者的編程經(jīng)驗(yàn)進(jìn)行評(píng)估。因?yàn)橐粋€(gè)大型的C/C++程序,勢(shì)必要涉及一些(甚至大量)進(jìn)行數(shù)據(jù)組合的結(jié)構(gòu)體,這些結(jié)構(gòu)體可以將原本意義屬于一個(gè)整體的數(shù)據(jù)組合在一起。從某種程度上來(lái)說(shuō),會(huì)不會(huì)用struct,怎樣用struct是區(qū)別一個(gè)開發(fā)人員是否具備豐富開發(fā)經(jīng)歷的標(biāo)志。

              在網(wǎng)絡(luò)協(xié)議、通信控制、嵌入式系統(tǒng)的C/C++編程中,我們經(jīng)常要傳送的不是簡(jiǎn)單的字節(jié)流(char型數(shù)組),而是多種數(shù)據(jù)組合起來(lái)的一個(gè)整體,其表現(xiàn)形式是一個(gè)結(jié)構(gòu)體。

              經(jīng)驗(yàn)不足的開發(fā)人員往往將所有需要傳送的內(nèi)容依順序保存在char型數(shù)組中,通過(guò)指針偏移的方法傳送網(wǎng)絡(luò)報(bào)文等信息。這樣做編程復(fù)雜,易出錯(cuò),而且一旦控制方式及通信協(xié)議有所變化,程序就要進(jìn)行非常細(xì)致的修改。

              一個(gè)有經(jīng)驗(yàn)的開發(fā)者則靈活運(yùn)用結(jié)構(gòu)體,舉一個(gè)例子,假設(shè)網(wǎng)絡(luò)或控制協(xié)議中需要傳送三種報(bào)文,其格式分別為packetA、packetB、packetC:

            struct structA
            {
            int a;
            char b;
            };

            struct structB
            {
            char a;
            short b;
            };

            struct structC
            {
            int a;
            char b;
            float c;
            }
              優(yōu)秀的程序設(shè)計(jì)者這樣設(shè)計(jì)傳送的報(bào)文:

            struct CommuPacket
            {
            int iPacketType;  //報(bào)文類型標(biāo)志
            union      //每次傳送的是三種報(bào)文中的一種,使用union
            {
            ? struct structA packetA;
            ? struct structB packetB;
            ? struct structC packetC;
            }
            };
              在進(jìn)行報(bào)文傳送時(shí),直接傳送struct CommuPacket一個(gè)整體。

              假設(shè)發(fā)送函數(shù)的原形如下:

            // pSendData:發(fā)送字節(jié)流的首地址,iLen:要發(fā)送的長(zhǎng)度
            Send(char * pSendData, unsigned int? iLen);
            發(fā)送方可以直接進(jìn)行如下調(diào)用發(fā)送struct CommuPacket的一個(gè)實(shí)例sendCommuPacket:
            Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
            假設(shè)接收函數(shù)的原形如下:
            // pRecvData:發(fā)送字節(jié)流的首地址,iLen:要接收的長(zhǎng)度
            //返回值:實(shí)際接收到的字節(jié)數(shù)
            unsigned int Recv(char * pRecvData, unsigned int? iLen);
              接收方可以直接進(jìn)行如下調(diào)用將接收到的數(shù)據(jù)保存在struct CommuPacket的一個(gè)實(shí)例recvCommuPacket中:

            Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );
              接著判斷報(bào)文類型進(jìn)行相應(yīng)處理:

            switch(recvCommuPacket. iPacketType)
            {
            ??? case PACKET_A:
            ??? …??? //A類報(bào)文處理
            ??? break;
            ??? case PACKET_B:
            ??? … ? //B類報(bào)文處理
            ??? break;
            ??? case PACKET_C:
            ??? …?? //C類報(bào)文處理
            ??? break;
            }
              以上程序中最值得注意的是

            Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
            Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );
              中的強(qiáng)制類型轉(zhuǎn)換:(char *)&sendCommuPacket、(char *)&recvCommuPacket,先取地址,再轉(zhuǎn)化為char型指針,這樣就可以直接利用處理字節(jié)流的函數(shù)。

              利用這種強(qiáng)制類型轉(zhuǎn)化,我們還可以方便程序的編寫,例如要對(duì)sendCommuPacket所處內(nèi)存初始化為0,可以這樣調(diào)用標(biāo)準(zhǔn)庫(kù)函數(shù)memset():

            memset((char *)&sendCommuPacket,0, sizeof(CommuPacket));

            2. struct的成員對(duì)齊
              Intel、微軟等公司曾經(jīng)出過(guò)一道類似的面試題:
            1. #include <iostream.h>
            2. #pragma pack(8)
            3. struct example1
            4. {
            5. short a;
            6. long b;
            7. };
            8. struct example2
            9. {
            10. char c;
            11. example1 struct1;
            12. short e;???
            13. };
            14. #pragma pack()
            15. int main(int argc, char* argv[])
            16. {
            17. example2 struct2;
            18. cout << sizeof(example1) << endl;
            19. cout << sizeof(example2) << endl;
            20. cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2) << endl;
            21. return 0;
            22. }
              問(wèn)程序的輸入結(jié)果是什么?
              答案是:
            8
            16
            4
              不明白?還是不明白?下面一一道來(lái):
            2.1 自然對(duì)界
              struct是一種復(fù)合數(shù)據(jù)類型,其構(gòu)成元素既可以是基本數(shù)據(jù)類型(如int、long、float等)的變量,也可以是一些復(fù)合數(shù)據(jù)類型(如array、struct、union等)的數(shù)據(jù)單元。對(duì)于結(jié)構(gòu)體,編譯器會(huì)自動(dòng)進(jìn)行成員變量的對(duì)齊,以提高運(yùn)算效率。缺省情況下,編譯器為結(jié)構(gòu)體的每個(gè)成員按其自然對(duì)界(natural alignment)條件分配空間。各個(gè)成員按照它們被聲明的順序在內(nèi)存中順序存儲(chǔ),第一個(gè)成員的地址和整個(gè)結(jié)構(gòu)的地址相同。
              自然對(duì)界(natural alignment)即默認(rèn)對(duì)齊方式,是指按結(jié)構(gòu)體的成員中size最大的成員對(duì)齊。
              例如:
            struct naturalalign
            {
            char a;
            short b;
            char c;
            };
              在上述結(jié)構(gòu)體中,size最大的是short,其長(zhǎng)度為2字節(jié),因而結(jié)構(gòu)體中的char成員a、c都以2為單位對(duì)齊,sizeof(naturalalign)的結(jié)果等于6;
              如果改為:
            struct naturalalign
            {
            char a;
            int b;
            char c;
            };
              其結(jié)果顯然為12。

            2.2指定對(duì)界
              一般地,可以通過(guò)下面的方法來(lái)改變?nèi)笔〉膶?duì)界條件:
              · 使用偽指令#pragma pack (n),編譯器將按照n個(gè)字節(jié)對(duì)齊;
              · 使用偽指令#pragma pack (),取消自定義字節(jié)對(duì)齊方式。
              注意:如果#pragma pack (n)中指定的n大于結(jié)構(gòu)體中最大成員的size,則其不起作用,結(jié)構(gòu)體仍然按照size最大的成員進(jìn)行對(duì)界。
              例如:
            #pragma pack (n)
            struct naturalalign
            {
            char a;
            int b;
            char c;
            };
            #pragma pack ()
              當(dāng)n為4、8、16時(shí),其對(duì)齊方式均一樣,sizeof(naturalalign)的結(jié)果都等于12。而當(dāng)n為2時(shí),其發(fā)揮了作用,使得sizeof(naturalalign)的結(jié)果為8。
              在VC++ 6.0編譯器中,我們可以指定其對(duì)界方式,其操作方式為依次選擇projetct > setting > C/C++菜單,在struct member alignment中指定你要的對(duì)界方式。
              另外,通過(guò)__attribute((aligned (n)))也可以讓所作用的結(jié)構(gòu)體成員對(duì)齊在n字節(jié)邊界上,但是它較少被使用,因而不作詳細(xì)講解。

            2.3 面試題的解答
              至此,我們可以對(duì)Intel、微軟的面試題進(jìn)行全面的解答。
              程序中第2行#pragma pack (8)雖然指定了對(duì)界為8,但是由于struct example1中的成員最大size為4(long變量size為4),故struct example1仍然按4字節(jié)對(duì)界,struct example1的size為8,即第18行的輸出結(jié)果;
              struct example2中包含了struct example1,其本身包含的簡(jiǎn)單數(shù)據(jù)成員的最大size為2(short變量e),但是因?yàn)槠浒藄truct example1,而struct example1中的最大成員size為4,struct example2也應(yīng)以4對(duì)界,#pragma pack (8)中指定的對(duì)界對(duì)struct example2也不起作用,故19行的輸出結(jié)果為16;
              由于struct example2中的成員以4為單位對(duì)界,故其char變量c后應(yīng)補(bǔ)充3個(gè)空,其后才是成員struct1的內(nèi)存空間,20行的輸出結(jié)果為4。

            posted @ 2006-07-06 21:20 Jerry Cat 閱讀(360) | 評(píng)論 (0)編輯 收藏
            [轉(zhuǎn)]WTL之父Nenad Stefanovic訪談錄

            ???作為現(xiàn)代C++最重要的特色技術(shù),template正在各個(gè)傳統(tǒng)領(lǐng)域攻城略地。從基本算法與數(shù)據(jù)結(jié)構(gòu),到正則表達(dá)式與XML解析,從高性能數(shù)學(xué)計(jì)算,到資源的分配與管理,從網(wǎng)絡(luò)分布式計(jì)算環(huán)境,到組件模型創(chuàng)建,從靜態(tài)多態(tài)性的維度擴(kuò)展,到設(shè)計(jì)模式的自動(dòng)生成,神奇的template顯示出其令人嘆為觀止的強(qiáng)勁實(shí)力,如果不是有一個(gè)隱隱的痛處,template愛(ài)好者簡(jiǎn)直可以去狂歡了。

            這個(gè)隱隱的痛處,就是在GUI編程領(lǐng)域。

            ???現(xiàn)有的大部分成熟GUI框架和工具庫(kù),其定型時(shí)間都在90年代早期,不管是因?yàn)槭裁丛?,總之我們根本看不到template技術(shù)在這些環(huán)境中的任何重要運(yùn)用。無(wú)論是專有MFC和OWL,還是開源的wxWindow和Mozilla, 以至于是專有還是開源都說(shuō)不清楚的Qt,它們?cè)谄渌矫嬗兄T多不同,偏偏倒是在對(duì)待模板技術(shù)上空前一致:嚴(yán)格限制在底層的數(shù)據(jù)結(jié)構(gòu)領(lǐng)域內(nèi),抵制模板技術(shù)流入GUI主體結(jié)構(gòu)。最過(guò)分的wxWindow和Mozilla,在代碼編寫規(guī)范里嚴(yán)厲禁止使用1990年之后發(fā)展出來(lái)的任何C++特性,模板、異常、多繼承、STL等等,均在黑名單上。諸位有興趣,不妨去看看,那與其說(shuō)是一份C++代碼編寫規(guī)范,倒不如說(shuō)是對(duì)C++現(xiàn)代特性在GUI領(lǐng)域應(yīng)用的一份不公正的判決書。

            難道模板技術(shù)真的在GUI領(lǐng)域無(wú)用武之地嗎?

            WTL給出了一個(gè)響亮的回答。

            ???WTL是微軟ATL開發(fā)組成員Nenad Stefanovic先生在ATL Windowing機(jī)制上發(fā)展起來(lái)的一整套GUI框架,運(yùn)用template技術(shù)組織和創(chuàng)建GUI對(duì)象,構(gòu)筑了精致的面向?qū)ο罂蚣埽](méi)錯(cuò),在這里object oriented與template達(dá)成了精致的融合)。雖然沒(méi)有獲得微軟的官方支持,雖然其使用者人數(shù)很少,但是確實(shí)是“用過(guò)的都說(shuō)好”,有位微軟MVP人士甚至說(shuō),這是微軟有史以來(lái)推出的最優(yōu)秀的一個(gè)framework。真是一個(gè)有趣的諷刺,最好的東西居然不被官方支持。有關(guān)于WTL的流言不少,比如這東西原本是微軟內(nèi)部專用,只是因?yàn)椴恍⌒牟疟恍孤┏鰜?lái)等等,這更加劇它的神秘色彩。相信大家對(duì)它一定有不少問(wèn)題。我們特別邀請(qǐng)到了WTL之父Nenad Stefanovic先生,進(jìn)行了一次網(wǎng)上的訪談,希望能幫助大家了解WTL的真面目。

            【C++ View】:I think most of our readers are not very familiar with you, so would you please tell us your story here? We are very fond of that. What do you think about China and Chinese people?

            【C++ View】:我想,可能我們的讀者中有很多人對(duì)您還不是很熟悉,您能不能在此給我們簡(jiǎn)單介紹一下您自己呢?我們將非常樂(lè)意聽(tīng)到您的自述。還有,您能不能也對(duì)我們講述一下您對(duì)于中國(guó)以及中國(guó)人民的基本看法呢?

            【Nenad】: I am a software developer at Microsoft. Your readers will probably know me as a creator of Windows Template Library, WTL. I am from former Yugoslavia, where I finished school and started working on software development. I've been living in US for 10 years now.

            I am intrigued and impressed by the Chinese culture and tradition. I think that China is now in a great position of progress as a country and a nation. I discovered that, being from former Yugoslavia, I already know many things about China, and getting to know people from China gave me a bit of the "everyday" life perspective as well. I'd like to learn more, so I hope to visit China one day.

            【Nenad】:好的。我現(xiàn)在在Microsoft工作,是它里面的一個(gè)軟件開發(fā)人員。你們雜志的讀者中可能有人知道,我就是Windows Template Library (WTL)的創(chuàng)作者。我來(lái)自于前南斯拉夫,在那我完成了我的學(xué)業(yè)并開始了我作為軟件開發(fā)人員的工作生涯。現(xiàn)在,我在美國(guó)居住的時(shí)間已經(jīng)超過(guò)了10年了。

            ???中國(guó)的文化以及傳統(tǒng)給我留下了極為深刻的印象,我對(duì)此十分感興趣。我想,作為一個(gè)國(guó)家以及民族,中國(guó)已經(jīng)處于一個(gè)偉大并且不斷在成長(zhǎng)中的位置上。作為一個(gè)從前南斯拉夫來(lái)的人,我早就了解到關(guān)于中國(guó)的很多事情。在與來(lái)自中國(guó)的人民的接觸過(guò)程中,我還了解到了你們?nèi)粘I畹囊恍顩r。我還想了解更多(有關(guān)中國(guó)的事情),希望有一天我可以到中國(guó)來(lái)游覽。

            【C++ View】:When and why did you first think about WTL? What's its original purpose? How do you see its future?

            【C++ View】:您是什么時(shí)候開始想起要開發(fā)WTL呢?為什么?您在開發(fā)它時(shí)的最初目的是什么?您又是如何地看待它未來(lái)的發(fā)展呢?

            【Nenad】:WTL was born while I was working on ATL (Active Template Library). We were extending ATL to support ActiveX controls, and I was working on the windowing support. I started thinking that the same techniques can be applied to much broader windowing support, for the much richer UI for controls, components, and also applications. So, WTL was created as a part of ATL that would extend ATL to support any kind of UI related component or application. It did not ship with ATL in Visual Studio, however, so I decided to ship it as a standalone library that extends ATL.

            I think that WTL will continue to be a great option for developers writing Windows applications and components. I don't see big changes or additions to WTL, because one of the design principles for WTL was to follow the Win32 UI API and design. It will continue to do so.

            【Nenad】:WTL是我在從事ATL (Active Template Library)開發(fā)工作時(shí)的產(chǎn)物。那時(shí)我們正在擴(kuò)展ATL,使之得以支持ActiveX control,而我負(fù)責(zé)的就是其中對(duì)于窗口機(jī)制部分的支持。這時(shí),我就開始想,是不是可以把同樣的技術(shù)應(yīng)用到更為廣泛的窗口機(jī)制中,以獲得更豐富的UI控制、組件、以至于應(yīng)用程序呢?于是,作為ATL的一部分,WTL被開發(fā)出來(lái)了。它將ATL進(jìn)行了擴(kuò)展,以使得它可以支持各種類型的與UI相關(guān)的組件或者應(yīng)用程序。然而,它并沒(méi)有隨著ATL一同集成在Visual Studio中被發(fā)布,于是我就決定將它作為一個(gè)單獨(dú)的ATL擴(kuò)展庫(kù)發(fā)布出去。

            我認(rèn)為WTL將一直是那些在Windows下開發(fā)應(yīng)用程序以及組件的開發(fā)者的一個(gè)很好的選擇。我并不認(rèn)為在以后,我們會(huì)對(duì)WTL有一個(gè)大的改動(dòng)(或者增添),因?yàn)閃TL的一個(gè)設(shè)計(jì)宗旨就是“遵循Win32 UI的API及其設(shè)計(jì)”?,F(xiàn)在如此,將來(lái)還是會(huì)如此下去。

            【C++ View】:I first heard about WTL in July, 2000. At that time, I thought: "No official support, no documentation, no commercial hype, it will die in 6 months." Now, fifteen months passed, it spreads wider and be more vigorous. Lots of C++ programmers, esp. the ones we regard them as "gurus and masters" involved in WTL. I know it's surely because WTL is a wonderful library, but it must be more than a wonderful library to gain such attentions without official force.What do you think WTL's relative success? What's the reason?

            【C++ View】:我第一次接觸WTL是在2000年7月。在那時(shí),我就想:“沒(méi)有官方的支持,沒(méi)有文檔,也沒(méi)有商業(yè)吹捧,它最多只能夠存活6個(gè)月?!钡F(xiàn)在15個(gè)月過(guò)去了,它反而流傳得更為廣泛,更加的生機(jī)勃勃。許多C++程序員,尤其是一些我們所認(rèn)知的“專家”以及“大師”,都在使用WTL。我當(dāng)然知道這主要是因?yàn)閃TL的出色,但我想,能夠在沒(méi)有官方的力量牽涉的情況下吸引如此多的注意,WTL一定還有更出色的東西,請(qǐng)問(wèn)您是如何看待WTL的成功呢?它成功的原因又是什么?

            【Nenad】: I think that the main reason of WTL's success is that it did fit the need of developers at the right time. More and more developers started using ATL, and it was natural for them to start using WTL when they needed more UI support. It seems that WTL was perceived as a more open project than others, judging by the support provided by other parties in the development community. Many people did a wonderful job of creating samples, documentation and support for WTL. The support from the programming community is very important part of the acceptance and success of WTL.

            【Nenad】:我認(rèn)為WTL成功的最主要原因就是,它確實(shí)而且及時(shí)地滿足了開發(fā)者的需求。越來(lái)越多的開發(fā)人員開始使用ATL,當(dāng)他們需要更多的UI支持時(shí),他們很自然的就會(huì)開始使用WTL。 從其他的開發(fā)團(tuán)隊(duì)所提供支持來(lái)看,WTL看起來(lái)似乎要比其他的項(xiàng)目更加開放。許許多多人為WTL做了大量工作,如:創(chuàng)建示例代碼,撰寫文檔等。WTL之所以能夠被廣為接受并獲得如此大的成功,來(lái)自于這些開發(fā)團(tuán)隊(duì)的支持絕對(duì)是一個(gè)重要的因素。

            【C++ View】:What do you think about MFC? Do you like it? If you don't, why? And the most confusing thing is Managed C++, is it C++? Do the leaders of MC++ really think some C++ users will go to learn it? Do you believe?

            【C++ View】:請(qǐng)問(wèn)您對(duì)于MFC是怎么看的?您喜歡它嗎?如果不,為什么呢?還有,最讓人迷惑不解的就是Managed C++了,它是不是C++呢?MC++的提倡者是不是真的認(rèn)為會(huì)有一些C++的用戶轉(zhuǎn)而去學(xué)習(xí)它呢?您的看法又是如何呢?

            【Nenad】: I think that MFC is a great framework library. Don't forget that MFC was designed at the time that C++ compiler was rather limited, and the main platform was 16-bit Windows. Unfortunately, because MFC was designed as a framework, it was really hard to evolve it to use better C++ support in newer compilers, and to add support for new features added to Windows in the meantime. What I don't like about MFC is the DLL approach, which causes many compatibility problems, and framework design, which dictates too many things about app design.

            Managed C++ is an extension to C++ which allows C++ programs to use managed code. It is very important to understand that you can compile your existing C++ code using MC++ without any changes. MC++ allows developers to use both familiar non-managed C++ and managed code in the same module. That provides an excellent way to extend existing code to interact with managed code, as well to create new projects that can use both managed and traditional C++.

            【Nenad】:我認(rèn)為MFC是一個(gè)了不起的框架庫(kù)。請(qǐng)不要忘了,在MFC被設(shè)計(jì)出來(lái)初期,那時(shí)的C++編譯器還具有很多的限制,并且那時(shí)主要的平臺(tái)還只是16位的Windows。不幸的是,由于MFC被設(shè)計(jì)成為一個(gè)框架,使得我們很難利用新編譯器中那些更好的C++特性來(lái)改進(jìn)它,也很難將Windows中的很多新特性添加到MFC中。我不喜歡MFC的地方是它高度依賴DLL的特性——因?yàn)樗鼘?dǎo)致許多兼容性方面的問(wèn)題;還有就是MFC的整個(gè)框架設(shè)計(jì)——它在應(yīng)用程序的設(shè)計(jì)中限定了太多東西。

            Managed C++是C++的一個(gè)擴(kuò)展,它允許C++程序得以使用受管(managed)代碼。我們需要了解的一個(gè)很重要的特性就是,我們可以使用MC++來(lái)編譯已有的C++代碼而無(wú)需對(duì)它們進(jìn)行任何改動(dòng)。MC++允許開發(fā)者同時(shí)使用他們所熟悉的非受管代碼以及受管代碼來(lái)開發(fā)同一個(gè)模塊。這就提供了一個(gè)非常好的途徑,使已有的代碼與新的受管代碼相互作用,并也可使得我們創(chuàng)建一個(gè)項(xiàng)目,同時(shí)使用受管的和傳統(tǒng)的C++代碼。

            【C++ View】:In the past 15 years or more, C and C++ is the base of almost all Microsoft's technologies(OS, COM, etc.). We C++ user paid a lot of hard work to catch them, because we felt what we paid was worthy(?). Now, it seems the climate changed. .NET is coming, the world is going to be full of CLRs and/or JVMs. There has been a decampment from C++. So what do you think about the future of C++ (not MC++) in Mircosoft technologies? Will it go away? Will it become a marginal language?

            【C++ View】:在過(guò)去的15年中(甚至更長(zhǎng)的一段時(shí)間內(nèi)),C以及C++構(gòu)成了幾乎所有Microsoft技術(shù)的基礎(chǔ)(如:OS,COM等)。我們這些C++用戶花費(fèi)了大量的時(shí)間來(lái)熟悉并掌握它們(C以及C++),因?yàn)槲覀兿嘈盼覀兯冻龅囊欢〞?huì)有回報(bào)(?)。但現(xiàn)在的風(fēng)向好像有了很大的改變。.NET出現(xiàn)了,世界似乎就要充斥CLR (Common Language Runtime,公共語(yǔ)言運(yùn)行庫(kù))以及/或JVM (Java Virtual Machine,Java虛擬機(jī))。現(xiàn)在C++已經(jīng)出現(xiàn)了退潮的跡象。那么,請(qǐng)問(wèn)您對(duì)于C++(不是MC++)在Microsoft技術(shù)中的前景如何看待?它是否會(huì)由此消亡?還是就此淪落為一門邊緣語(yǔ)言?

            【Nenad】:Well, the world is changing too. The new type of development for Web services and connected applications is on the horizon. I think that new languages, like Java, C#, and VB.NET, were developed to address two main issues - to simplify software development and to provide better support for Internet development. Simplifying software development allows more developers to write good applications and cuts down on time needed to finish a project. Supporting Internet development is obviously very important in this time when Internet is used more and more in every part of everyday life.

            I think that C++ will continue to be an important language, especially for ISV's and for system development. On the other hand, I believe that .NET will be very important platform soon. .NET has the potential to be the main programming platform for the future, but it is reasonable to expect that the transition will take some time.

            【Nenad】:是的,世界也已經(jīng)發(fā)生了變化。對(duì)于網(wǎng)絡(luò)服務(wù)以及連接這樣的新型應(yīng)用程序的開發(fā)已經(jīng)浮上了水面。我認(rèn)為那些新的編程語(yǔ)言(如Java,C#,以及VB.NET)都是針對(duì)以下兩個(gè)主要的問(wèn)題而開發(fā)出來(lái)的——簡(jiǎn)化軟件的開發(fā)過(guò)程以及對(duì)于Internet應(yīng)用程序開發(fā)提供更好的的支持。簡(jiǎn)化軟件的開發(fā)過(guò)程使得更多的開發(fā)者可以寫出更多更好的應(yīng)用程序并減少完成開發(fā)項(xiàng)目所需要的時(shí)間。而支持Internet的開發(fā),對(duì)于這個(gè)Internet越來(lái)越深入到我們的日常生活中的時(shí)代來(lái)說(shuō),毫無(wú)疑問(wèn)是一件非常重要的事情。

            我認(rèn)為C++會(huì)繼續(xù)作為一門重要的編程語(yǔ)言發(fā)揮作用,尤其是對(duì)那些獨(dú)立軟件開發(fā)商和那些系統(tǒng)級(jí)開發(fā)來(lái)說(shuō)更是如此。從另一方面來(lái)說(shuō),我相信.NET將會(huì)在不久以后成為另外一個(gè)非常重要的開發(fā)平臺(tái)。對(duì)于未來(lái)來(lái)說(shuō),.NET擁有成為主流編程平臺(tái)的潛力,但我們必須認(rèn)識(shí)到,這樣的過(guò)渡階段肯定要持續(xù)一段時(shí)間。

            【C++ View】:There a lots of beginners in our readers, after they learn (standard) C++, they want to seek a path to master enought Microsoft technologies to be practical and proficient programmers. Could you recommend such a path? Should they learn Win32 API programming? Is it worthy of studying MFC? Is WTL/ATL/STL a reliable solution? Or goto C# directly? Many many people will thank you if you give them frank advice.

            【C++ View】:我們的讀者中有很多是初學(xué)者,在他們學(xué)習(xí)完(標(biāo)準(zhǔn))C++后,他們希望能夠找到一條道路,掌握到足夠多的Microsoft的技術(shù)使自己成為經(jīng)驗(yàn)豐富的、熟練的程序員。您能不能給我們指出這樣的一條道路來(lái)呢?我們是不是應(yīng)該學(xué)習(xí)Win32 API編程?學(xué)習(xí)MFC是否是值得的?WTL/ATL/STL算得上是一個(gè)可靠的解決方案嗎?又或是我們應(yīng)該直接學(xué)習(xí)C#?如果您能夠給我們一些建議,相信會(huì)有很多的人為此而感激您的。

            【Nenad】:I think that depends on their plans and ambitions. The more of those things you do, the better you are off in the long run. But, you also have to balance that with the practical issues. So, I think that people who see their future in the Internet development can go directly to C# or VB.NET, and study .NET platform. Those who would like to have more knowledge of the Windows platform and services it provides should certainly learn more about Win32 API and libraries that support Windows programming.

            【Nenad】:我認(rèn)為這主要取決于他們的計(jì)劃以及雄心。你所做的越多,在長(zhǎng)時(shí)間競(jìng)爭(zhēng)中你就越占據(jù)優(yōu)勢(shì)。不過(guò)你也要注意保持與實(shí)際問(wèn)題的平衡。我建議那些決心以后只做Internet相關(guān)開發(fā)的人可以直接去學(xué)習(xí)C#或者VB.NET,同時(shí)學(xué)習(xí).NET平臺(tái)。而那些更多地了解Windows平臺(tái)以及它所提供的服務(wù)方面知識(shí)的人,當(dāng)然就必須需要更多地了解有關(guān)Win32 API以及那些支持Windows編程的庫(kù)相關(guān)的知識(shí)。

            【C++ View】:Soon after I began to learn WTL, a warm-hearted man posted me a email. He wrote: "You won't be a good WTL programmer if not a good ATL programmer, you won't be a good ATL programmer if not a COM programmer. And once you decide to learn COM, you are beginning your travel to hell." Is COM so difficult to learn? How to study WTL? We must learn API, COM, ATL and WTL in sequence, do we? And what about COM, will it remain to be the core technology of Microsoft, or just be substituted by .NET and dismiss?

            【C++ View】:在我剛開始學(xué)習(xí)WTL后不久,有一位熱心人給我發(fā)了份郵件。他寫道:“如果你不是一個(gè)好的ATL程序員的話,你就不可能成為一個(gè)好的WTL程序員;如果你不會(huì)COM編程的話,你就不可能成為一個(gè)好的ATL程序員;但一旦你決定開始學(xué)習(xí)COM,你就邁出了踏向地獄的第一步?!盋OM是不是真的那么難學(xué)?我們應(yīng)該如何地來(lái)學(xué)習(xí)WTL呢?我們是不是應(yīng)該按照這樣的順序?qū)W下來(lái)呢,API->COM->ATL->WTL?還有,COM將會(huì)變得如何?他是不是還能夠保持Microsoft的核心技術(shù)這一頭銜,抑或是被.NET給替換掉然后就此消失?

            【Nenad】:I don't think it is necessary to master COM to use and understand WTL. Win32 UI knowledge is more important than COM to understand WTL. But it is true that knowledge of ATL is required, and ATL mainly supports COM. So, COM knowledge is desirable, but not required.

            I don't think that COM is hell, but it sure does require a lot to learn to be an expert. Keep in mind that many people don't have to be COM experts to use COM, or to use WTL. Just understanding basic principles of COM is enough to use it, and then people can learn more when needed.

            【Nenad】:我不認(rèn)為使用和理解WTL就一定要掌握COM。相比于COM來(lái)說(shuō),Win32 UI的知識(shí)對(duì)于理解WTL顯得更為重要。但毫無(wú)疑問(wèn)的是,ATL的相關(guān)知識(shí)是必不可少的。由于ATL主要任務(wù)就是支持COM,所以,有COM的知識(shí)只是會(huì)更好一些而已,但它們并不是必需的。

            我也不認(rèn)為COM是一個(gè)噩夢(mèng),但毫無(wú)疑問(wèn)的是,想要成為一個(gè)COM專家,要學(xué)的東西實(shí)在是太多了。但請(qǐng)記住一件事情,很多使用COM或者WTL的人并不都是COM方面的專家。要想使用它們,人們所需了解的只是一些COM的基本原理就夠了,其他的相關(guān)的知識(shí)則可以在需要時(shí)再去學(xué)習(xí)。

            【C++ View】:What do you think about Generic Programming? Is it a whole different paradigm from OOP, or just OOP's supplemental facility? Can we combine GP and OOP? In the hard work of design and implement WTL, you must had got an insight about the relationship between OOP and GP, what's it?

            【C++ View】:請(qǐng)問(wèn)您對(duì)于泛型程序設(shè)計(jì)是如何看待的?它到底是OOP的一個(gè)補(bǔ)充呢,還是完全不同于OOP的另外一個(gè)程序設(shè)計(jì)范型呢?我們是否可以將GP以及OOP一同聯(lián)合使用?我想,在設(shè)計(jì)和實(shí)作出WTL的艱苦過(guò)程中,對(duì)于OOP以及GP之間的關(guān)系,您一定有了自己的看法,您能不能給我們說(shuō)一下呢?

            【Nenad】:Generic Programming and OOP are very different, mostly because Generic Programming doesn't explicitly express relationships between design elements. They can, however, be used together very efficiently.

            WTL uses a combination of Generic Programming and OOP design. Templates are mostly used to implement traditional OOP classes. I'd like to point out that WTL doesn't use any "pure" design, and it doesn't strictly follow any design guidelines or styles. I do think, though, that WTL does use one of the main strengths of the C++ language - it uses appropriate paradigm that is the most suitable for a particular problem.

            【Nenad】:GP和OOP非常不同,這主要是由于GP從不顯式地表達(dá)出設(shè)計(jì)元素之間的關(guān)聯(lián)來(lái)。然而,它們也可以被非常高效地組合運(yùn)用。

            WTL中使用了一種GP連同OOP的設(shè)計(jì)。我在其中大量使用了模板來(lái)實(shí)作出傳統(tǒng)的OOP中的類。我很樂(lè)意指出的是,WTL中并沒(méi)有使用一種“純”設(shè)計(jì),它也沒(méi)有遵循任何的設(shè)計(jì)指導(dǎo)方針或者設(shè)計(jì)規(guī)格??墒?,我還是認(rèn)為WTL使用到了C++語(yǔ)言中的最主要的精髓處——對(duì)于一個(gè)特定的問(wèn)題使用一種最適合它的適當(dāng)?shù)浞丁?

            【C++ View】:Recently, the famous C++ pioneer Stanley Lippman joined Microsoft and became a member of Visual C++.NET group. How do you think about this? What message do you think your company like to pass to public? Does this mean Microsoft want to make VC.NET a full-standardized C++ compiler and hold C++ as your core system language?

            【C++ View】:最近,著名的C++元老級(jí)大師Stanley Lippman加入了Microsoft并成為其VC.NET開發(fā)小組中的一員。請(qǐng)問(wèn)您對(duì)于此事是如何看待的?您認(rèn)為Microsoft試圖向公眾傳播一種什么樣的信息呢?這是否也意味著Microsoft希望VC.NET成為一個(gè)完全標(biāo)準(zhǔn)化的C++編譯器,并繼續(xù)保持C++的核心系統(tǒng)語(yǔ)言地位呢?

            【Nenad】:I think that shows that Microsoft is committed to advance the C++ compiler and language, and ready to get the best people to help. I am sure that VC++.NET will continue to be powerful tool for developing applications, and that it will also include additional capabilities for the .NET development. Compliance with the C++ Standard is an ongoing work, and we will see further improvements there, too.

            【Nenad】:我認(rèn)為這顯示了Microsoft對(duì)于促進(jìn)C++編譯器以及語(yǔ)言繼續(xù)發(fā)展的決心,并為此找到了最佳人選來(lái)獲取幫助。我確信VC.NET將會(huì)繼續(xù)是開發(fā)應(yīng)用程序的強(qiáng)有力工具,并且它同時(shí)還將包含有.NET開發(fā)能力。目前我們正在進(jìn)行兼容C++標(biāo)準(zhǔn)方面的工作,不久我們就會(huì)看到成效。

            【C++ View】:I'm learning WTL and ATL, since you are the author of WTL and a member of ATL group, can you give me some advice?

            【C++ View】:我現(xiàn)在正在學(xué)習(xí)WTL以及ATL,既然您是WTL的作者,同時(shí)又是ATL開發(fā)小組中的一員,您能不能給我一些建議呢?

            【Nenad】:There are several areas of programming that are very important for WTL and ATL: knowledge of the C++ language in general, understanding of templates, COM for ATL, and Windows UI programming for WTL. Solid knowledge in these areas is very beneficial for WTL and ATL developers, and it also helps to understand the source code for both libraries.

            I would also like to encourage everybody to write programs. That is the best way to learn how to use any library, or a programming language or operating system. Writing programs often brings problems that must be solved that are not addressed in books. Reading about something is very useful to start learning, writing programs is the best next step.

            【Nenad】:對(duì)于WTL和ATL來(lái)說(shuō),有好幾個(gè)編程方面的領(lǐng)域是十分重要的:大體上的C++語(yǔ)言知識(shí),了解模板,COM(對(duì)ATL而言),以及Windows UI編程(對(duì)WTL而言)。在這些領(lǐng)域有著堅(jiān)實(shí)的基礎(chǔ)對(duì)于WTL以及ATL開發(fā)人員來(lái)說(shuō)有著很大的好處,同時(shí)對(duì)于理解這兩個(gè)的源代碼也能夠起到幫助作用。

            我同樣也很樂(lè)意去鼓勵(lì)大家多寫程序。這也是學(xué)習(xí)如何使用一個(gè)程序庫(kù),或者一門編程語(yǔ)言,或者一個(gè)操作系統(tǒng)的一個(gè)最好的方法。在寫程序的過(guò)程中經(jīng)常會(huì)出現(xiàn)一些書本上沒(méi)有提及但又必須被解決的問(wèn)題。在開始學(xué)習(xí)時(shí)讀一些東西是很有用的,而寫程序則是向縱深發(fā)展的最佳方式。

            【C++ View】:They say we are in the gate of Post-PC times, it will be a embedded world, and there will be embedded smart device everywhere, and the embedded industry will build a far large market compare to PC's. Do you believe it? Do you think WTL and other C++ template libraries are available and appropriate for embedded development? Are there available for Internet development?

            【C++ View】:有人說(shuō),我們現(xiàn)在已經(jīng)處于后PC時(shí)代的門口,未來(lái)將會(huì)是一個(gè)嵌入系統(tǒng)的世界,嵌入式的智能設(shè)備將會(huì)無(wú)所不在,并且對(duì)比PC來(lái)說(shuō),嵌入系統(tǒng)的產(chǎn)業(yè)將會(huì)是一個(gè)更大的市場(chǎng)。您是否相信這些呢?您是否認(rèn)為WTL以及其他的一些C++模板庫(kù)對(duì)于嵌入式開發(fā)也適用呢?它們是否適合Internet開發(fā)?

            【Nenad】:Yes, I think that large number of various devices that we use everyday will become small, specialized computers. That doesn't mean that the number and importance of PCs will go down, just that there are many other devices that will be enhanced to be programmable and connected. Those new devices will provide a great opportunity for software developers, because they will all have software and somebody has to write it.

            Many of the C++ libraries are quite appropriate for embedded development, and WTL would also be in cases where Windows based user interface is important (for example, Pocket PC platform). Great flexibility and small footprint are always very important features for embedded development, so template libraries are in the very good position there.

            【Nenad】:是的,我認(rèn)為我們現(xiàn)今所使用的各種設(shè)備中的大部分在以后都將會(huì)演變成為一些小的,具有專門用途的計(jì)算機(jī)。但這并不意味著PC的數(shù)目以及重要性將會(huì)由此降低,只不過(guò)是表明還有著許多其他的設(shè)備需要被加強(qiáng)以使得我們可以對(duì)其進(jìn)行編程并且連接。由于必須需要有軟件的支持,而軟件又需要有人來(lái)寫,這些新的設(shè)備將會(huì)給軟件開發(fā)人員帶來(lái)極大的機(jī)遇。

            有許多的C++函數(shù)庫(kù)都可用于嵌入系統(tǒng)的開發(fā),WTL也將會(huì)在那些Windows用戶界面較為重要的開發(fā)中(例如,在Pocket PC平臺(tái)上面開發(fā))占有一席之地。對(duì)于嵌入式開發(fā)來(lái)說(shuō),良好的彈性,微小的內(nèi)存耗用永遠(yuǎn)都會(huì)是很重要的特性,而模板庫(kù)在這方面占據(jù)了一個(gè)非常好的地位。

            【C++ View】:In the past 7 years or more, COM is Microsoft's core technology. And we now can see that in the next decade, the core role may be .NET. My question is, what's wrong with COM? Where will COM be? Will it disappear? Will it be substituted by something else? What's the relationship between COM and .NET? Is .NET based on COM? Is it worthy of learning COM now?

            【C++ View】:在過(guò)去的7年(甚至更長(zhǎng)的一段時(shí)間)內(nèi),COM都是Microsoft中的核心技術(shù)。現(xiàn)在我們可以預(yù)見(jiàn)到,在下一個(gè)十年間,這個(gè)核心將會(huì)變?yōu)?NET。我的問(wèn)題就是,COM有什么過(guò)錯(cuò)?COM將何去何從?它是否會(huì)逐漸消失呢,還是會(huì)被其他的一些技術(shù)給替代?COM和.NET之間的關(guān)系是什么樣的情況?.NET是否是基于COM之上呢?現(xiàn)在學(xué)習(xí)COM是不是還值得?

            【Nenad】:Maybe you shouldn't ask what is wrong with COM, but just think of .NET as the evolution of COM. .NET extends what was started with COM- creating reusable binary components - and brings additional important features: rich metadata, great run-time, built-in security, versioning, etc. All of these new features are important for development today, and it is really great that .NET has extensive support for them. Interoperability between .NET and COM is also provided, so that the previously developed COM components can still be used in the .NET environment.

            I still think that it is a good idea to learn COM - it is a great first step even for people who want to learn .NET, and it also provides better understanding of the design and implementation of .NET itself.

            【Nenad】:或許你不應(yīng)該問(wèn)COM有什么過(guò)錯(cuò),而是應(yīng)該把.NET看成COM的進(jìn)化。.NET擴(kuò)展了COM最初的目的——?jiǎng)?chuàng)建可重用的二進(jìn)制程序組件——并向其中添加了很多重要的特性:豐富的元數(shù)據(jù),了不起的運(yùn)行庫(kù),內(nèi)建的安全機(jī)制,版本機(jī)制等。對(duì)于現(xiàn)今的軟件開發(fā)來(lái)說(shuō),所有的這些新的特性都非常重要,所以.NET能夠廣泛地支持它們,是一件很偉大的產(chǎn)品。Microsoft同時(shí)也提供了在.NET和COM之間進(jìn)行互操作的能力,這使得以前所開發(fā)出來(lái)的COM組件在.NET環(huán)境中同樣也能夠得到使用。

            我仍然認(rèn)為學(xué)習(xí)COM是一個(gè)很好的主意——它甚至對(duì)于那些希望學(xué)習(xí).NET的人們來(lái)說(shuō)也是一個(gè)很好的開端,學(xué)習(xí)COM同時(shí)也有助于我們更深入地理解 .NET本身的設(shè)計(jì)和實(shí)現(xiàn)。

            【C++ View】:I know you must be a C++ fan. Now the language is facing lots of challenges. To counterattack, Dr. Stroustrup suggest to develop many useful libraries, and teach the programmers to use C++ as a high level language. Now there are several wonderful modern C++ libraries. Aside of ATL, WTL and STL, there are still Boost library, MTL, ACE/TAO, DTL, etc. It seems the C++ community is preparing a movement. Do you think the movement will success? Why? What are your colleagues'(in Microsoft VC.NET group) attitude towards such a movement?

            【C++ View】:我猜想您肯定是一個(gè)C++愛(ài)好者?,F(xiàn)在這門語(yǔ)言面對(duì)著許多的挑戰(zhàn)。作為反擊措施,Stroustrup博士提議開發(fā)許多有用的庫(kù),并引導(dǎo)C++程序員把C++當(dāng)作一門高級(jí)語(yǔ)言來(lái)使用?,F(xiàn)在我們已經(jīng)可以得到好幾個(gè)極好的現(xiàn)代的C++庫(kù),除去ATL、WTL以及STL之外,還有Boost庫(kù)、MTL、ACE/TAO、DTL等。一切都顯示著C++社區(qū)正在醞釀著一次變革。請(qǐng)問(wèn)您覺(jué)得這場(chǎng)變革能否成功?為什么?您的那些Microsoft中的VC.NET開發(fā)小組中的同事對(duì)于此態(tài)度是怎樣的?

            【Nenad】:C++ is a great language and its importance remains high, even with the new challenges. Libraries are an excellent addition to the language itself, as they provide very useful reusable code for developers. The existence of many great C++ libraries shows the size and strength of the C++ community. I think that is already a success, and that it will continue. You can be sure that the VC++.NET group is aware of the existing libraries, and I expect them to continue to enhance the support for them.

            【Nenad】:C++是一門偉大的語(yǔ)言,即便遇到了新的挑戰(zhàn),它仍然將是非常重要的。程序庫(kù)對(duì)于語(yǔ)言本身是極好的補(bǔ)充,它們?yōu)殚_發(fā)者提供了一些十分有用的可重用代碼。存在如此眾多的、了不起C++程序庫(kù),這件事情本身就表明了C++社區(qū)的龐大和強(qiáng)大。我認(rèn)為這場(chǎng)變革已經(jīng)成功了,并且會(huì)一直成功下去。你們可以放心,VC.NET開發(fā)組是不會(huì)對(duì)這些已有的程序庫(kù)熟視無(wú)睹的,我預(yù)期他們會(huì)不斷地加強(qiáng)對(duì)于這些庫(kù)的支持。

            【C++ View】:The last question. Since lots of people don’t acquaint themselves with WTL, now we have a chance for you, the father of WTL, to introduce WTL in a short speech here. What would you like to speak?

            【C++ View】:最后一個(gè)問(wèn)題。既然許多人并不了解WTL,作為WTL之父,您現(xiàn)在有機(jī)會(huì)在這里做一個(gè)演講,請(qǐng)簡(jiǎn)短地介紹一下WTL。

            【Nenad】:WTL is a template based library for user interface development. It extends ATL to provide classes for implementing user interface for applications, components, and controls. It provides classes for various user interface elements: top-level windows, MDI, standard and common controls, common dialogs, property sheets and pages, GDI objects, UI updating, scrollable windows, splitter windows, command bars, etc.

            WTL is implemented using the same template architecture as ATL, so it is a natural fit for ATL developers. It also doesn't alter or hide Windows specific constructs, thus allowing Windows programmers to use WTL without surprises. The important design goal of WTL was to avoid inter-dependencies - classes themselves do not reference other WTL classes. That means that your program will contain just the code that you actually use, and nothing else. Coupled with the use of templates, this allows creation of very small programs without run-time dependencies.

            WTL delivers the object oriented way to program for the Windows user interface, while keeping the code size small. It also provides a great foundation that developers can extend with their own classes.

            And finally - WTL was written with a hope that developers will enjoy using it. I hope you will use it and enjoy it, too.

            WTL是一個(gè)基于模板的、專為開發(fā)用戶界面的程序庫(kù)。它擴(kuò)展了ATL,并提供了一些類用來(lái)實(shí)現(xiàn)應(yīng)用程序的用戶界面、組件和控件。它提供了各種類來(lái)支持各種各樣的用戶界面元素:頂級(jí)窗口、MDI、標(biāo)準(zhǔn)控件和通用控件、通用的對(duì)話框、屬性表以及屬性頁(yè)、GDI對(duì)象、UI更新、可卷動(dòng)的窗口、分割窗口、命令條等等……

            WTL的實(shí)現(xiàn)使用了和ATL一樣的模板架構(gòu),所以對(duì)于ATL開發(fā)者顯得很自然。同時(shí)它并沒(méi)有改變或者是隱藏那些Windows相關(guān)結(jié)構(gòu),那些Windows程序員在使用WTL時(shí)也不會(huì)感到很吃驚。WTL的一個(gè)主要設(shè)計(jì)原則就是避免在沒(méi)有引用到其他WTL類時(shí),出現(xiàn)不必要的內(nèi)部依賴。這意味著我們的程序?qū)⒅话形覀儗?shí)際上所使用的代碼,除此之外再無(wú)其他的東西。加上了模板的使用后,這樣做得到的結(jié)果就是一些非常小的,不依賴于運(yùn)行庫(kù)的程序。

            WTL專注于用面向?qū)ο蟮姆椒▉?lái)編寫Windows的用戶界面程序,同時(shí)保持代碼的尺寸很小。同時(shí),它也為開發(fā)者提供了一個(gè)很好的基礎(chǔ),可以寫新的類來(lái)擴(kuò)展WTL。

            最后,我在編寫WTL時(shí)就希望開發(fā)者能夠喜歡在開發(fā)中使用它。我同樣也希望您能夠使用它并喜歡上它。

            posted @ 2006-07-05 23:15 Jerry Cat 閱讀(180) | 評(píng)論 (0)編輯 收藏
            [轉(zhuǎn)]Run time type Information

            一???????????????? dynamic_cast
            < type-id > ( expression )
            ? type-id :必須是指針或者引用
            ? expression:必須是指針或者一個(gè)左值
            基本上是用來(lái)做 子對(duì)象間的轉(zhuǎn)換
            1.基本的用法
            				class B { ... };
            class C : public B { ... };
            class D : public C { ... };
            
            void f(D* pd)
            {
               C* pc = dynamic_cast<C*>(pd);   // ok: C is a direct base class
                                             // pc points to C subobject of pd 
            
               B* pb = dynamic_cast<B*>(pd);   // ok: B is an indirect base class
                                             // pb points to B subobject of pd 
               ...
            }
            		

            This type of conversion is called an "upcast" because it moves a pointer up a class hierarchy, from a derived class to a class it is derived from. An upcast is an implicit conversion.

            If type-id is void*, a run-time check is made to determine the actual type of expression. The result is a pointer to the complete object pointed to by expression. For example:

            				class A { ... };
            
            class B { ... };
            
            void f()
            {
               A* pa = new A;
               B* pb = new B;
               void* pv = dynamic_cast<void*>(pa);
               // pv now points to an object of type A
               ...
               pv = dynamic_cast<void*>(pb);
               // pv now points to an object of type B
            }
            		

            If type-id is not void*, a run-time check is made to see if the object pointed to by expression can be converted to the type pointed to by type-id.

            If the type of expression is a base class of the type of type-id, a run-time check is made to see if expression actually points to a complete object of the type of type-id. If this is true, the result is a pointer to a complete object of the type of type-id. For example:

            				class B { ... };
            class D : public B { ... };
            
            void f()
            {
               B* pb = new D;                     // unclear but ok
               B* pb2 = new B;
            
               D* pd = dynamic_cast<D*>(pb);      // ok: pb actually points to a D
               ...
               D* pd2 = dynamic_cast<D*>(pb2);   // pb2 points to a B not a D
                                                // cast was bad so pd2 == NULL
               ...
            }
            		

            This type of conversion is called a "downcast" because it moves a pointer down a class hierarchy, from a given class to a class derived from it.
            小結(jié):
            ? a???? 實(shí)際指向?qū)ο?和?? b 目標(biāo)對(duì)象,? b 是a 的 基類(子對(duì)象),或者是2者 同級(jí)轉(zhuǎn)換才成功
            否則 目標(biāo)為NULL;也就是說(shuō)不能向下轉(zhuǎn)



            2?? 多重非虛的繼承模式

            Class Hierarchy Showing Multiple Inheritance

            A pointer to an object of type D can be safely cast to B or C. However, if D is cast to point to an A object, which instance of A would result? This would result in an ambiguous casting error. To get around this problem, you can perform two unambiguous casts. For example:

            				void f()
            {
               D* pd = new D;
               A* pa = dynamic_cast<A*>(pd);      // error: ambiguous
               B* pb = dynamic_cast<B*>(pd);      // first cast to B
               A* pa2 = dynamic_cast<A*>(pb);   // ok: unambiguous
            }
            		

            Further ambiguities can be introduced when you use virtual base classes. Consider the class hierarchy shown in the following figure.

            ??? 也就是說(shuō)在2意性下會(huì)失敗
            3.子對(duì)象間的轉(zhuǎn)換

            Class Hierarchy Showing Duplicate Base Classes

            ????//pd 指向 e 對(duì)象
            void f(D* pd)
            {
            ?? E* pe = dynamic_cast<E*>(pd);
            ?? B* pb = pe;????? // upcast, implicit conversion
            ?? A* pa = pb;????? // upcast, implicit conversion
            }

            //pd 指向 e 對(duì)象
            void f(D* pd)
            {
            ?? B* pb = dynamic_cast<B*>(pd);????? // cross cast
            ?? A* pa = pb;????????????????? // upcast, implicit conversion
            }

            ? 也就是? 所謂 cross cast

            二? typeid( type-id )???? typeid( expression )?
            ?? 此操作符返回個(gè)? const type_info &?
            ??????????? expression?必須指向一個(gè)多態(tài)類型(帶虛函數(shù)??? ),并且要解引用

            #include <iostream>
            #include <typeinfo.h>

            class Base {
            public:
            ?? virtual void vvfunc() {}
            };

            class Derived : public Base {};

            using namespace std;
            int main()
            {
            ?? Derived* pd = new Derived;
            ?? Base* pb = pd;
            ?? cout << typeid( pb ).name() << endl;?? //prints "class Base *"
            ?? cout << typeid( *pb ).name() << endl;?? //prints "class Derived"
            ?? cout << typeid( pd ).name() << endl;?? //prints "class Derived *"
            ?? cout << typeid( *pd ).name() << endl;?? //prints "class Derived"
            ?? delete pd;
            }
            // compile with: /GR /EHsc

            在模版中使用
            template < typename T > T max( T arg1, T arg2 ) {
            ?? cout << typeid( T ).name() << "s compared." << endl;
            ?? return ( arg1 > arg2 ? arg1 : arg2 );
            }

            -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

            還不知道dynamic_cast<void*>()能轉(zhuǎn)換成真實(shí)類型的指針。有這個(gè)功能,真太好了。
            等C++0x出來(lái)后,就可以用:
            auto pv = dynamic_cast<void*>(...)來(lái)獲取真實(shí)類型了。

            posted @ 2006-07-04 21:03 Jerry Cat 閱讀(331) | 評(píng)論 (0)編輯 收藏
            一次關(guān)于旨在降低編譯時(shí)間的整改工作(vc++)
            [轉(zhuǎn)自]天爬者


            由于工程的文件的日益龐大和第3方庫(kù)(ACE Loki Boost等等)的使用增多
            我所工作的項(xiàng)目系統(tǒng)構(gòu)建時(shí)間從最初的3分鐘變?yōu)楝F(xiàn)在的8分鐘
            程序員的機(jī)器配置已經(jīng)很不錯(cuò)了,3。0 的主頻1g的內(nèi)存,但是常常由于一個(gè)小的修改導(dǎo)致5分鐘甚至更長(zhǎng)的編譯時(shí)間來(lái)驗(yàn)證效果。

            按照《Joel on software》的說(shuō)法,其直接后果是可怕的:
            程序員們?cè)谶@8分鐘內(nèi)無(wú)所事事,只有查看網(wǎng)頁(yè),或者qqmsn,打斷先前的思路從他們的上下文環(huán)境里面脫離了出來(lái),離開了“順勢(shì)工作時(shí)間”,等到他們編譯好了驗(yàn)證再修改的時(shí)候,他們又得花不少的時(shí)間來(lái)回到剛才的思路

            “順勢(shì)工作時(shí)間”大致意思就是說(shuō)2個(gè)不連續(xù)的半小時(shí)的效果遠(yuǎn)不如一個(gè)連續(xù)沉浸的1小時(shí)的工作效果,如果一個(gè)人不能連續(xù)沉浸的思考,那么他就很可能陷入在不停的上下文環(huán)境切換和淺表思考當(dāng)中。人的多線程處理和機(jī)器是一樣的環(huán)境的切換不能夠不考慮

            所以,在當(dāng)前機(jī)器配置已經(jīng)沒(méi)有什么提升空間的情況下,我在項(xiàng)目組內(nèi)部組織了一次整改活動(dòng),旨在降低編譯構(gòu)建時(shí)間


            1。目標(biāo):將完全重新編譯時(shí)間從8分鐘降低到4分鐘以下
            2。原則:通過(guò)和主程序的溝通,并參考了《C++ coding Standards》出了一下幾條整改原則:
            ?????首先是關(guān)于include的,因?yàn)榘^文件相當(dāng)于將代碼復(fù)制到本文件來(lái)編譯,而頭文件又經(jīng)常是用來(lái)被別人包含的,所以工程文件多了,每個(gè)文件都有include鏈(包含的文件又include了其他文件),該鏈條不會(huì)止步于你工程,而會(huì)延伸到你所有使用的第3方庫(kù)里面

            ?????A.
            能夠去掉的include就去掉。

            ?????B.能夠在cpp
            里面include的頭文件不要在頭文件里面include。
            ?????
            說(shuō)明:盡量去掉每個(gè)cpp會(huì)被串起來(lái)的頭文件膨脹的機(jī)會(huì)

            ?????
            C.能夠用前向聲明的就不要include,頭文件里面也是一樣
            ???? 說(shuō)明:在頭文件里面用前向聲明然后保存指針或者引用,在具體實(shí)現(xiàn)的cpp里面再包含頭文件,雖然看起來(lái)和《C++ coding Standards》“
            Make header files self-sufficient ”有些沖突(前兩天另外cppblog一位朋友講過(guò) http://www.shnenglu.com/flyingxu/archive/2006/06/23/8908.html )但是在一些核心的.h(被很多類include的)里面作改造工作,還是能夠收到很大的降低編譯時(shí)間效果,而付出的代價(jià)就是原來(lái)只需要包含該頭文件就可以編譯成功的cpp需要額外包含一些頭文件。

            舉個(gè)例子: Foo類頭文件使用了前向申明保存了A類和B類的指針或者引用為成員變量,在Foo類的cpp里面才包含A和B的頭文件,而當(dāng)C類需要使用Foo類時(shí)候包含F(xiàn)oo類的頭文件,但是操作中又需要調(diào)用A的成員函數(shù),C不同時(shí)包含A的頭文件的花就會(huì)出現(xiàn)編譯失敗。

            雖然表面上是讓代碼更加復(fù)雜了,但是除卻帶來(lái)降低編譯時(shí)間的好處之外,代碼也在強(qiáng)迫你進(jìn)行解耦合,如果說(shuō)你cpp里面需要包含的頭文件越多,說(shuō)明你這個(gè)類需要知道的對(duì)象就越多,你可以乘機(jī)檢查一下自己的代碼又沒(méi)有不必要的耦合,為什么這個(gè)cpp需要知道那么多的本來(lái)可能屬于別的類的細(xì)節(jié).....

            ??????D。
            把大多數(shù)模塊都要使用的庫(kù)文件或者穩(wěn)定類的頭文件include放到預(yù)編譯頭文件“stdafx.h”里面
            ??????
            說(shuō)明:由于預(yù)編譯頭文件里面include的內(nèi)容只會(huì)compile一次而被link多次,把一些常用類放到這里會(huì)降低很多編譯時(shí)間,但也不能亂來(lái),要點(diǎn)在于 “大多數(shù)”和“穩(wěn)定”,如果一個(gè)頭文件經(jīng)常變化,他的一次小改動(dòng)都會(huì)引起整個(gè)工程rebuild,哪怕只是一個(gè)注釋,因?yàn)樗械腸pp文件都包含了stdafx.h而stdafx.h又包含了這個(gè)容易變動(dòng)的頭文件。
            ??????
            ??????
            E.使用Pimpl慣用法
            ??????說(shuō)明:關(guān)于Pimpl大家可以查下資料,《C++ coding Standards》里面也有講解,基本上就是采用一個(gè)私有的前向申明的stuct指針把所有protect成員都封裝起來(lái)起來(lái).基本上是一個(gè)最終極的解決方案,但是對(duì)我們現(xiàn)有架構(gòu)改造太大,不敢全面實(shí)行,我們只選擇了數(shù)個(gè)最有價(jià)值的類進(jìn)行了改造,打算以后在其他項(xiàng)目里面再全面應(yīng)用。

            3。實(shí)施: 通過(guò)半個(gè)小時(shí)的溝通,讓項(xiàng)目組程序員了解原則,并采取結(jié)隊(duì)修改的方式來(lái)降低引入新bug的風(fēng)險(xiǎn),在以通過(guò)原有單元測(cè)試用例的條件下,進(jìn)行修改-測(cè)試-提交的迭代。
            ???

            4。結(jié)果:???編
            譯時(shí)間降低到了6分鐘以內(nèi)。。。雖沒(méi)有達(dá)到預(yù)期,但也算有效果,沒(méi)有完全達(dá)標(biāo)的主要原因還是沒(méi)有完整的測(cè)試方案包括單元測(cè)試和驗(yàn)收測(cè)試,怕有些改動(dòng)過(guò)大影響系統(tǒng)健壯性,局部放棄了一些實(shí)施的原則。


            把這個(gè)整改的工作寫出來(lái),一方面作個(gè)記錄,另外一方面希望和大家討論,相互多多交流:)
            posted @ 2006-07-04 03:38 Jerry Cat 閱讀(506) | 評(píng)論 (1)編輯 收藏
            [轉(zhuǎn)]Windows進(jìn)程中的內(nèi)存結(jié)構(gòu)

            在閱讀本文之前,如果你連堆棧是什么多不知道的話,請(qǐng)先閱讀文章后面的基礎(chǔ)知識(shí)。
            ?
            ?接觸過(guò)編程的人都知道,高級(jí)語(yǔ)言都能通過(guò)變量名來(lái)訪問(wèn)內(nèi)存中的數(shù)據(jù)。那么這些變量在內(nèi)存中是如何存放的呢?程序又是如何使用這些變量的呢?下面就會(huì)對(duì)此進(jìn)行深入的討論。下文中的C語(yǔ)言代碼如沒(méi)有特別聲明,默認(rèn)都使用VC編譯的release版。
            ?
            ?首先,來(lái)了解一下 C 語(yǔ)言的變量是如何在內(nèi)存分部的。C 語(yǔ)言有全局變量(Global)、本地變量(Local),靜態(tài)變量(Static)、寄存器變量(Regeister)。每種變量都有不同的分配方式。先來(lái)看下面這段代碼:
            ?
            ?#include <stdio.h>
            ?
            ?int g1=0, g2=0, g3=0;
            ?
            ?int main()
            ?{
            ?static int s1=0, s2=0, s3=0;
            ?int v1=0, v2=0, v3=0;
            ?
            ?//打印出各個(gè)變量的內(nèi)存地址
            ?
            ?printf("0x%08x\n",&v1); //打印各本地變量的內(nèi)存地址
            ?printf("0x%08x\n",&v2);
            ?printf("0x%08x\n\n",&v3);
            ?printf("0x%08x\n",&g1); //打印各全局變量的內(nèi)存地址
            ?printf("0x%08x\n",&g2);
            ?printf("0x%08x\n\n",&g3);
            ?printf("0x%08x\n",&s1); //打印各靜態(tài)變量的內(nèi)存地址
            ?printf("0x%08x\n",&s2);
            ?printf("0x%08x\n\n",&s3);
            ?return 0;
            ?}
            ?
            ?編譯后的執(zhí)行結(jié)果是:
            ?
            ?0x0012ff78
            ?0x0012ff7c
            ?0x0012ff80
            ?
            ?0x004068d0
            ?0x004068d4
            ?0x004068d8
            ?
            ?0x004068dc
            ?0x004068e0
            ?0x004068e4
            ?
            ?輸出的結(jié)果就是變量的內(nèi)存地址。其中v1,v2,v3是本地變量,g1,g2,g3是全局變量,s1,s2,s3是靜態(tài)變量。你可以看到這些變量在內(nèi)存是連續(xù)分布的,但是本地變量和全局變量分配的內(nèi)存地址差了十萬(wàn)八千里,而全局變量和靜態(tài)變量分配的內(nèi)存是連續(xù)的。這是因?yàn)楸镜刈兞亢腿?靜態(tài)變量是分配在不同類型的內(nèi)存區(qū)域中的結(jié)果。對(duì)于一個(gè)進(jìn)程的內(nèi)存空間而言,可以在邏輯上分成3個(gè)部份:代碼區(qū),靜態(tài)數(shù)據(jù)區(qū)和動(dòng)態(tài)數(shù)據(jù)區(qū)。動(dòng)態(tài)數(shù)據(jù)區(qū)一般就是“堆棧”?!皸?stack)”和“堆(heap)”是兩種不同的動(dòng)態(tài)數(shù)據(jù)區(qū),棧是一種線性結(jié)構(gòu),堆是一種鏈?zhǔn)浇Y(jié)構(gòu)。進(jìn)程的每個(gè)線程都有私有的“?!保悦總€(gè)線程雖然代碼一樣,但本地變量的數(shù)據(jù)都是互不干擾。一個(gè)堆??梢酝ㄟ^(guò)“基地址”和“棧頂”地址來(lái)描述。全局變量和靜態(tài)變量分配在靜態(tài)數(shù)據(jù)區(qū),本地變量分配在動(dòng)態(tài)數(shù)據(jù)區(qū),即堆棧中。程序通過(guò)堆棧的基地址和偏移量來(lái)訪問(wèn)本地變量。
            ?
            ?
            ?├———————┤低端內(nèi)存區(qū)域
            ?│ …… │
            ?├———————┤
            ?│ 動(dòng)態(tài)數(shù)據(jù)區(qū) │
            ?├———————┤
            ?│ …… │
            ?├———————┤
            ?│ 代碼區(qū) │
            ?├———————┤
            ?│ 靜態(tài)數(shù)據(jù)區(qū) │
            ?├———————┤
            ?│ …… │
            ?├———————┤高端內(nèi)存區(qū)域
            ?
            ?
            ?堆棧是一個(gè)先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu),棧頂?shù)刂房偸切∮诘扔跅5幕刂?。我們可以先了解一下函?shù)調(diào)用的過(guò)程,以便對(duì)堆棧在程序中的作用有更深入的了解。不同的語(yǔ)言有不同的函數(shù)調(diào)用規(guī)定,這些因素有參數(shù)的壓入規(guī)則和堆棧的平衡。windows API的調(diào)用規(guī)則和ANSI C的函數(shù)調(diào)用規(guī)則是不一樣的,前者由被調(diào)函數(shù)調(diào)整堆棧,后者由調(diào)用者調(diào)整堆棧。兩者通過(guò)“__stdcall”和“__cdecl”前綴區(qū)分。先看下面這段代碼:
            ?
            ?#include <stdio.h>
            ?
            ?void __stdcall func(int param1,int param2,int param3)
            ?{
            ?int var1=param1;
            ?int var2=param2;
            ?int var3=param3;
            ?printf("0x%08x\n",?m1); //打印出各個(gè)變量的內(nèi)存地址
            ?printf("0x%08x\n",?m2);
            ?printf("0x%08x\n\n",?m3);
            ?printf("0x%08x\n",&var1);
            ?printf("0x%08x\n",&var2);
            ?printf("0x%08x\n\n",&var3);
            ?return;
            ?}
            ?
            ?int main()
            ?{
            ?func(1,2,3);
            ?return 0;
            ?}
            ?
            ?編譯后的執(zhí)行結(jié)果是:
            ?
            ?0x0012ff78
            ?0x0012ff7c
            ?0x0012ff80
            ?
            ?0x0012ff68
            ?0x0012ff6c
            ?0x0012ff70
            ?
            ?
            ?
            ?├———————┤<—函數(shù)執(zhí)行時(shí)的棧頂(ESP)、低端內(nèi)存區(qū)域
            ?│ …… │
            ?├———————┤
            ?│ var 1 │
            ?├———————┤
            ?│ var 2 │
            ?├———————┤
            ?│ var 3 │
            ?├———————┤
            ?│ RET │
            ?├———————┤<—“__cdecl”函數(shù)返回后的棧頂(ESP)
            ?│ parameter 1 │
            ?├———————┤
            ?│ parameter 2 │
            ?├———————┤
            ?│ parameter 3 │
            ?├———————┤<—“__stdcall”函數(shù)返回后的棧頂(ESP)
            ?│ …… │
            ?├———————┤<—棧底(基地址 EBP)、高端內(nèi)存區(qū)域
            ?
            ?
            ?上圖就是函數(shù)調(diào)用過(guò)程中堆棧的樣子了。首先,三個(gè)參數(shù)以從又到左的次序壓入堆棧,先壓“param3”,再壓“param2”,最后壓入“param1”;然后壓入函數(shù)的返回地址(RET),接著跳轉(zhuǎn)到函數(shù)地址接著執(zhí)行(這里要補(bǔ)充一點(diǎn),介紹UNIX下的緩沖溢出原理的文章中都提到在壓入RET后,繼續(xù)壓入當(dāng)前EBP,然后用當(dāng)前ESP代替EBP。然而,有一篇介紹windows下函數(shù)調(diào)用的文章中說(shuō),在windows下的函數(shù)調(diào)用也有這一步驟,但根據(jù)我的實(shí)際調(diào)試,并未發(fā)現(xiàn)這一步,這還可以從param3和var1之間只有4字節(jié)的間隙這點(diǎn)看出來(lái));第三步,將棧頂(ESP)減去一個(gè)數(shù),為本地變量分配內(nèi)存空間,上例中是減去12字節(jié)(ESP=ESP-3*4,每個(gè)int變量占用4個(gè)字節(jié));接著就初始化本地變量的內(nèi)存空間。由于“__stdcall”調(diào)用由被調(diào)函數(shù)調(diào)整堆棧,所以在函數(shù)返回前要恢復(fù)堆棧,先回收本地變量占用的內(nèi)存(ESP=ESP+3*4),然后取出返回地址,填入EIP寄存器,回收先前壓入?yún)?shù)占用的內(nèi)存(ESP=ESP+3*4),繼續(xù)執(zhí)行調(diào)用者的代碼。參見(jiàn)下列匯編代碼:
            ?
            ?;--------------func 函數(shù)的匯編代碼-------------------
            ?
            ?:00401000 83EC0C sub esp, 0000000C //創(chuàng)建本地變量的內(nèi)存空間
            ?:00401003 8B442410 mov eax, dword ptr [esp+10]
            ?:00401007 8B4C2414 mov ecx, dword ptr [esp+14]
            ?:0040100B 8B542418 mov edx, dword ptr [esp+18]
            ?:0040100F 89442400 mov dword ptr [esp], eax
            ?:00401013 8D442410 lea eax, dword ptr [esp+10]
            ?:00401017 894C2404 mov dword ptr [esp+04], ecx
            ?
            ?……………………(省略若干代碼)
            ?
            ?:00401075 83C43C add esp, 0000003C ;恢復(fù)堆棧,回收本地變量的內(nèi)存空間
            ?:00401078 C3 ret 000C ;函數(shù)返回,恢復(fù)參數(shù)占用的內(nèi)存空間
            ?;如果是“__cdecl”的話,這里是“ret”,堆棧將由調(diào)用者恢復(fù)
            ?
            ?;-------------------函數(shù)結(jié)束-------------------------
            ?
            ?
            ?;--------------主程序調(diào)用func函數(shù)的代碼--------------
            ?
            ?:00401080 6A03 push 00000003 //壓入?yún)?shù)param3
            ?:00401082 6A02 push 00000002 //壓入?yún)?shù)param2
            ?:00401084 6A01 push 00000001 //壓入?yún)?shù)param1
            ?:00401086 E875FFFFFF call 00401000 //調(diào)用func函數(shù)
            ?;如果是“__cdecl”的話,將在這里恢復(fù)堆棧,“add esp, 0000000C”
            ?
            ?聰明的讀者看到這里,差不多就明白緩沖溢出的原理了。先來(lái)看下面的代碼:
            ?
            ?#include <stdio.h>
            ?#include <string.h>
            ?
            ?void __stdcall func()
            ?{
            ?char lpBuff[8]="\0";
            ?strcat(lpBuff,"AAAAAAAAAAA");
            ?return;
            ?}
            ?
            ?int main()
            ?{
            ?func();
            ?return 0;
            ?}
            ?
            ?編譯后執(zhí)行一下回怎么樣?哈,“"0x00414141"指令引用的"0x00000000"內(nèi)存。該內(nèi)存不能為"read"。”,“非法操作”嘍!"41"就是"A"的16進(jìn)制的ASCII碼了,那明顯就是strcat這句出的問(wèn)題了。"lpBuff"的大小只有8字節(jié),算進(jìn)結(jié)尾的‘\0‘,那strcat最多只能寫入7個(gè)"A",但程序?qū)嶋H寫入了11個(gè)"A"外加1個(gè)‘\0‘。再來(lái)看看上面那幅圖,多出來(lái)的4個(gè)字節(jié)正好覆蓋了RET的所在的內(nèi)存空間,導(dǎo)致函數(shù)返回到一個(gè)錯(cuò)誤的內(nèi)存地址,執(zhí)行了錯(cuò)誤的指令。如果能精心構(gòu)造這個(gè)字符串,使它分成三部分,前一部份僅僅是填充的無(wú)意義數(shù)據(jù)以達(dá)到溢出的目的,接著是一個(gè)覆蓋RET的數(shù)據(jù),緊接著是一段shellcode,那只要著個(gè)RET地址能指向這段shellcode的第一個(gè)指令,那函數(shù)返回時(shí)就能執(zhí)行shellcode了。但是軟件的不同版本和不同的運(yùn)行環(huán)境都可能影響這段shellcode在內(nèi)存中的位置,那么要構(gòu)造這個(gè)RET是十分困難的。一般都在RET和shellcode之間填充大量的NOP指令,使得exploit有更強(qiáng)的通用性。
            ?
            ?
            ?├———————┤<—低端內(nèi)存區(qū)域
            ?│ …… │
            ?├———————┤<—由exploit填入數(shù)據(jù)的開始
            ?│ │
            ?│ buffer │<—填入無(wú)用的數(shù)據(jù)
            ?│ │
            ?├———————┤
            ?│ RET │<—指向shellcode,或NOP指令的范圍
            ?├———————┤
            ?│ NOP │
            ?│ …… │<—填入的NOP指令,是RET可指向的范圍
            ?│ NOP │
            ?├———————┤
            ?│ │
            ?│ shellcode │
            ?│ │
            ?├———————┤<—由exploit填入數(shù)據(jù)的結(jié)束
            ?│ …… │
            ?├———————┤<—高端內(nèi)存區(qū)域
            ?
            ?
            ?windows下的動(dòng)態(tài)數(shù)據(jù)除了可存放在棧中,還可以存放在堆中。了解C++的朋友都知道,C++可以使用new關(guān)鍵字來(lái)動(dòng)態(tài)分配內(nèi)存。來(lái)看下面的C++代碼:
            ?
            ?#include <stdio.h>
            ?#include
            ?#include <windows.h>
            ?
            ?void func()
            ?{
            ?char *buffer=new char[128];
            ?char bufflocal[128];
            ?static char buffstatic[128];
            ?printf("0x%08x\n",buffer); //打印堆中變量的內(nèi)存地址
            ?printf("0x%08x\n",bufflocal); //打印本地變量的內(nèi)存地址
            ?printf("0x%08x\n",buffstatic); //打印靜態(tài)變量的內(nèi)存地址
            ?}
            ?
            ?void main()
            ?{
            ?func();
            ?return;
            ?}
            ?
            ?程序執(zhí)行結(jié)果為:
            ?
            ?0x004107d0
            ?0x0012ff04
            ?0x004068c0
            ?
            ?可以發(fā)現(xiàn)用new關(guān)鍵字分配的內(nèi)存即不在棧中,也不在靜態(tài)數(shù)據(jù)區(qū)。VC編譯器是通過(guò)windows下的“堆(heap)”來(lái)實(shí)現(xiàn)new關(guān)鍵字的內(nèi)存動(dòng)態(tài)分配。在講“堆”之前,先來(lái)了解一下和“堆”有關(guān)的幾個(gè)API函數(shù):
            ?
            ?HeapAlloc 在堆中申請(qǐng)內(nèi)存空間
            ?HeapCreate 創(chuàng)建一個(gè)新的堆對(duì)象
            ?HeapDestroy 銷毀一個(gè)堆對(duì)象
            ?HeapFree 釋放申請(qǐng)的內(nèi)存
            ?HeapWalk 枚舉堆對(duì)象的所有內(nèi)存塊
            ?GetProcessHeap 取得進(jìn)程的默認(rèn)堆對(duì)象
            ?GetProcessHeaps 取得進(jìn)程所有的堆對(duì)象
            ?LocalAlloc
            ?GlobalAlloc
            ?
            ?當(dāng)進(jìn)程初始化時(shí),系統(tǒng)會(huì)自動(dòng)為進(jìn)程創(chuàng)建一個(gè)默認(rèn)堆,這個(gè)堆默認(rèn)所占內(nèi)存的大小為1M。堆對(duì)象由系統(tǒng)進(jìn)行管理,它在內(nèi)存中以鏈?zhǔn)浇Y(jié)構(gòu)存在。通過(guò)下面的代碼可以通過(guò)堆動(dòng)態(tài)申請(qǐng)內(nèi)存空間:
            ?
            ?HANDLE hHeap=GetProcessHeap();
            ?char *buff=HeapAlloc(hHeap,0,8);
            ?
            ?其中hHeap是堆對(duì)象的句柄,buff是指向申請(qǐng)的內(nèi)存空間的地址。那這個(gè)hHeap究竟是什么呢?它的值有什么意義嗎?看看下面這段代碼吧:
            ?
            ?#pragma comment(linker,"/entry:main") //定義程序的入口
            ?#include <windows.h>
            ?
            ?_CRTIMP int (__cdecl *printf)(const char *, ...); //定義STL函數(shù)printf
            ?/*---------------------------------------------------------------------------
            ?寫到這里,我們順便來(lái)復(fù)習(xí)一下前面所講的知識(shí):
            ?(*注)printf函數(shù)是C語(yǔ)言的標(biāo)準(zhǔn)函數(shù)庫(kù)中函數(shù),VC的標(biāo)準(zhǔn)函數(shù)庫(kù)由msvcrt.dll模塊實(shí)現(xiàn)。
            ?由函數(shù)定義可見(jiàn),printf的參數(shù)個(gè)數(shù)是可變的,函數(shù)內(nèi)部無(wú)法預(yù)先知道調(diào)用者壓入的參數(shù)個(gè)數(shù),函數(shù)只能通過(guò)分析第一個(gè)參數(shù)字符串的格式來(lái)獲得壓入?yún)?shù)的信息,由于這里參數(shù)的個(gè)數(shù)是動(dòng)態(tài)的,所以必須由調(diào)用者來(lái)平衡堆棧,這里便使用了__cdecl調(diào)用規(guī)則。BTW,Windows系統(tǒng)的API函數(shù)基本上是__stdcall調(diào)用形式,只有一個(gè)API例外,那就是wsprintf,它使用__cdecl調(diào)用規(guī)則,同printf函數(shù)一樣,這是由于它的參數(shù)個(gè)數(shù)是可變的緣故。
            ?---------------------------------------------------------------------------*/
            ?void main()
            ?{
            ?HANDLE hHeap=GetProcessHeap();
            ?char *buff=HeapAlloc(hHeap,0,0x10);
            ?char *buff2=HeapAlloc(hHeap,0,0x10);
            ?HMODULE hMsvcrt=LoadLibrary("msvcrt.dll");
            ?printf=(void *)GetProcAddress(hMsvcrt,"printf");
            ?printf("0x%08x\n",hHeap);
            ?printf("0x%08x\n",buff);
            ?printf("0x%08x\n\n",buff2);
            ?}
            ?
            ?執(zhí)行結(jié)果為:
            ?
            ?0x00130000
            ?0x00133100
            ?0x00133118
            ?
            ?hHeap的值怎么和那個(gè)buff的值那么接近呢?其實(shí)hHeap這個(gè)句柄就是指向HEAP首部的地址。在進(jìn)程的用戶區(qū)存著一個(gè)叫PEB(進(jìn)程環(huán)境塊)的結(jié)構(gòu),這個(gè)結(jié)構(gòu)中存放著一些有關(guān)進(jìn)程的重要信息,其中在PEB首地址偏移0x18處存放的ProcessHeap就是進(jìn)程默認(rèn)堆的地址,而偏移0x90處存放了指向進(jìn)程所有堆的地址列表的指針。windows有很多API都使用進(jìn)程的默認(rèn)堆來(lái)存放動(dòng)態(tài)數(shù)據(jù),如windows 2000下的所有ANSI版本的函數(shù)都是在默認(rèn)堆中申請(qǐng)內(nèi)存來(lái)轉(zhuǎn)換ANSI字符串到Unicode字符串的。對(duì)一個(gè)堆的訪問(wèn)是順序進(jìn)行的,同一時(shí)刻只能有一個(gè)線程訪問(wèn)堆中的數(shù)據(jù),當(dāng)多個(gè)線程同時(shí)有訪問(wèn)要求時(shí),只能排隊(duì)等待,這樣便造成程序執(zhí)行效率下降。
            ?
            ?最后來(lái)說(shuō)說(shuō)內(nèi)存中的數(shù)據(jù)對(duì)齊。所位數(shù)據(jù)對(duì)齊,是指數(shù)據(jù)所在的內(nèi)存地址必須是該數(shù)據(jù)長(zhǎng)度的整數(shù)倍,DWORD數(shù)據(jù)的內(nèi)存起始地址能被4除盡,WORD數(shù)據(jù)的內(nèi)存起始地址能被2除盡,x86 CPU能直接訪問(wèn)對(duì)齊的數(shù)據(jù),當(dāng)他試圖訪問(wèn)一個(gè)未對(duì)齊的數(shù)據(jù)時(shí),會(huì)在內(nèi)部進(jìn)行一系列的調(diào)整,這些調(diào)整對(duì)于程序來(lái)說(shuō)是透明的,但是會(huì)降低運(yùn)行速度,所以編譯器在編譯程序時(shí)會(huì)盡量保證數(shù)據(jù)對(duì)齊。同樣一段代碼,我們來(lái)看看用VC、Dev-C++和lcc三個(gè)不同編譯器編譯出來(lái)的程序的執(zhí)行結(jié)果:
            ?
            ?#include <stdio.h>
            ?
            ?int main()
            ?{
            ?int a;
            ?char b;
            ?int c;
            ?printf("0x%08x\n",&a);
            ?printf("0x%08x\n",&b);
            ?printf("0x%08x\n",&c);
            ?return 0;
            ?}
            ?
            ?這是用VC編譯后的執(zhí)行結(jié)果:
            ?0x0012ff7c
            ?0x0012ff7b
            ?0x0012ff80
            ?變量在內(nèi)存中的順序:b(1字節(jié))-a(4字節(jié))-c(4字節(jié))。
            ?
            ?這是用Dev-C++編譯后的執(zhí)行結(jié)果:
            ?0x0022ff7c
            ?0x0022ff7b
            ?0x0022ff74
            ?變量在內(nèi)存中的順序:c(4字節(jié))-中間相隔3字節(jié)-b(占1字節(jié))-a(4字節(jié))。
            ?
            ?這是用lcc編譯后的執(zhí)行結(jié)果:
            ?0x0012ff6c
            ?0x0012ff6b
            ?0x0012ff64
            ?變量在內(nèi)存中的順序:同上。
            ?
            ?三個(gè)編譯器都做到了數(shù)據(jù)對(duì)齊,但是后兩個(gè)編譯器顯然沒(méi)VC“聰明”,讓一個(gè)char占了4字節(jié),浪費(fèi)內(nèi)存哦。
            ?
            ?
            ?基礎(chǔ)知識(shí):
            ?堆棧是一種簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu),是一種只允許在其一端進(jìn)行插入或刪除的線性表。允許插入或刪除操作的一端稱為棧頂,另一端稱為棧底,對(duì)堆棧的插入和刪除操作被稱為入棧和出棧。有一組CPU指令可以實(shí)現(xiàn)對(duì)進(jìn)程的內(nèi)存實(shí)現(xiàn)堆棧訪問(wèn)。其中,POP指令實(shí)現(xiàn)出棧操作,PUSH指令實(shí)現(xiàn)入棧操作。CPU的ESP寄存器存放當(dāng)前線程的棧頂指針,EBP寄存器中保存當(dāng)前線程的棧底指針。CPU的EIP寄存器存放下一個(gè)CPU指令存放的內(nèi)存地址,當(dāng)CPU執(zhí)行完當(dāng)前的指令后,從EIP寄存器中讀取下一條指令的內(nèi)存地址,然后繼續(xù)執(zhí)行。
            ?
            ?
            ?參考:《Windows下的HEAP溢出及其利用》by: isno
            ????????????? 《windows核心編程》by: Jeffrey Richter
            posted @ 2006-07-02 20:57 Jerry Cat 閱讀(311) | 評(píng)論 (0)編輯 收藏

            /********************************************\
            |????歡迎轉(zhuǎn)載, 但請(qǐng)保留作者姓名和原文鏈接, 祝您進(jìn)步并共勉!???? |
            \********************************************/


            c語(yǔ)言中的類型轉(zhuǎn)換與復(fù)合類型

            作者: Jerry Cat
            時(shí)間: 2006/07/01
            鏈接: http://www.shnenglu.com/jerysun0818/archive/2006/07/01/9274.html

            數(shù)據(jù)類型轉(zhuǎn)換是C語(yǔ)言中頗具爭(zhēng)議的一個(gè)話題,這里不多加評(píng)論,單就其中整形與浮點(diǎn)型之間的轉(zhuǎn)換做一些解說(shuō).?
            由于表示范圍的原因,你可能認(rèn)為把整型數(shù)轉(zhuǎn)換為浮點(diǎn)型一定是安全的,但實(shí)際上不是這么簡(jiǎn)單。因?yàn)楦↑c(diǎn)型存儲(chǔ)的數(shù)值雖然大但卻受精度的限制。
            如unsigned int u=4294967295;
            float f=u;
            接過(guò)f變成了4294967296.000000
            所以要把一個(gè)整形換成float在轉(zhuǎn)換回來(lái)還要和原先的數(shù)相同,則這個(gè)數(shù)只能有6位有效數(shù)字。否則會(huì)有精度損失。而要把浮點(diǎn)換成整形,首先可以肯定小數(shù)部分被舍掉了。另外還要注意,轉(zhuǎn)換的第一步必須是以下的一種類型:
            int???? unsigned???? long???? unsigned long???? long long???? unsigned long long??
            如:
            float f=12345.678;
            int i=f;
            short s=i;
            否則直接轉(zhuǎn)換到short 得到的就根本不是12345了。(與平臺(tái)有關(guān),windows不存在這個(gè)問(wèn)題)

            對(duì)于復(fù)合類型,主要是要注意由于數(shù)據(jù)對(duì)齊要求而導(dǎo)致的存儲(chǔ)空間浪費(fèi)。這里舉一個(gè)例子:
            struct s
            {
            ??? char x;
            ??? int y;
            ??? char z;
            ??? int u;
            };???????????? /*s占16個(gè)字節(jié)*/
            struct s
            {
            ??? int y;??? /*4*/
            ??? int u;??? /*4*/
            ??? char x;??? /*1*/
            ??? char z;??? /*3*/
            };???????????? /*s占12個(gè)字節(jié)*/
            注意這里第二個(gè)定義中為什么不是10,這還是由于數(shù)據(jù)對(duì)齊的原因,因?yàn)椴荒苤豢紤]單個(gè)變量的情況,還有可能是結(jié)構(gòu)體數(shù)組變量,struct?s array[10],知道原因了吧。另外一種可能就是在函數(shù)調(diào)用中,結(jié)構(gòu)體變量作為一個(gè)參數(shù)要壓棧,是以4字節(jié)為一個(gè)單元壓棧的。

            posted @ 2006-07-01 18:49 Jerry Cat 閱讀(911) | 評(píng)論 (1)編輯 收藏
            僅列出標(biāo)題
            共14頁(yè): First 4 5 6 7 8 9 10 11 12 Last 

            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿(7)

            隨筆檔案

            最新隨筆

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久国产精品一国产精品金尊| 色播久久人人爽人人爽人人片AV| 久久综合亚洲欧美成人| 国产成人久久精品区一区二区| 久久成人国产精品二三区| 久久亚洲中文字幕精品一区| 2021国产精品久久精品| 国产精品久久精品| 久久久久波多野结衣高潮| 久久99国产精品二区不卡| 久久精品国产免费观看| 国产高潮国产高潮久久久91| 亚洲级αV无码毛片久久精品| 亚洲综合久久综合激情久久| 亚洲国产综合久久天堂| 2020最新久久久视精品爱 | 99久久婷婷国产综合精品草原| 亚洲精品综合久久| 精品久久国产一区二区三区香蕉 | 亚洲国产美女精品久久久久∴| 激情久久久久久久久久| 99久久国产热无码精品免费 | 色综合久久88色综合天天| 亚洲国产欧美国产综合久久 | 久久免费精品一区二区| 青青草原精品99久久精品66| 三级三级久久三级久久| 日韩AV毛片精品久久久| 久久久久国产精品嫩草影院 | 一本久久精品一区二区| 日本久久久久久久久久| 久久亚洲av无码精品浪潮| segui久久国产精品| 久久久中文字幕| 国产成人精品久久| 久久激情五月丁香伊人| 国产亚洲色婷婷久久99精品91| 91精品国产91久久| 国产精品免费久久久久久久久| 丰满少妇人妻久久久久久4| 99久久精品无码一区二区毛片|