﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-My C++</title><link>http://www.cppblog.com/finehai/</link><description>当时只道是寻常~</description><language>zh-cn</language><lastBuildDate>Sat, 04 Apr 2026 12:49:56 GMT</lastBuildDate><pubDate>Sat, 04 Apr 2026 12:49:56 GMT</pubDate><ttl>60</ttl><item><title>【转】这些道理不懂，你注定就是穷打工的命</title><link>http://www.cppblog.com/finehai/archive/2012/04/28/173042.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Sat, 28 Apr 2012 06:50:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/28/173042.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/173042.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/28/173042.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/173042.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/173042.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt; font-family: Arial;"> </span><div><span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: #000000; word-spacing: 0px;"><span style="line-height: 18px; font-family: Arial,Helvetica,sans-serif; color: #333333; font-size: 12px;"><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 12pt; font-family: Arial;"><br /></span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">同样是打工</span><span style="font-size: 10pt; font-family: Arial;">，为什么你一个月只有2、3K，而唐骏的身价却可以高达10亿？或许你会反驳我，说人人都成为唐骏的概率有多大？的确，人人都成为唐骏的确不现 实，但是经过努力，月薪达到8K、1W的总是大有人在吧？虽然不能达到大富大贵，但也不至于买不起房子，成天挤在合租房吧？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">很多人都喜欢抱怨，觉得这个世道不好。但现实是，在同样世道不好的情况下，为什么有的人成功，而你却碌碌无为？差距在哪里？怪世道不好吗？还是怪自己没本 事？我说这话可能你不爱听。但是一个无法辩驳的事实是：你要是有本事，为什么月薪只有2、3K或者3、4K？事实胜于雄辩。所以，如果看到这里还想抱怨的 人，那么，也请你趁早离开。抱怨永远解决不了问题。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">职 场是一个复杂的综合体。看到别人在职场上呼风唤雨，你认为很惬意，是么？但是他们风光表面的背后，又有几个有看到他们曾经付出的巨大艰辛？这个社会其实是 很公平的。努力不一定有回报，但如果不努力，就一定没有回报。要怪，就怪自己投错胎，怪自己的老子没本事，当初没有给你留下一大笔可以挥霍的资本！</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">说 归说，对于那些想改变自己的朋友们来说，还是需要看清楚一些东西，有一些经验也想和大家分享分享。同样是职场人士，我也有我的经验和感受。在打工的3年 里，我得到了7次加薪（同时进入公司的员工，加薪不超过2次的员工大有人在），顺利地从员工做到了总监，是公司所有员工中成长最快的。我敢肯定，在看过这 篇文章的人当中，肯定有人比我更优秀。但是对于那些更渴望得到帮助的朋友们来说，我还是希望把自己的经验写出来，与大家分享。有人问我成功有没有捷径，我 告诉他，唯一的捷径就是不走弯路。以下的9条如果你做到了，成功对你而言，只是个时间问题。</span></p><br style="line-height: 18px;" /> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 10pt; font-family: Arial;">一、一定要清楚自己未来的目标是什么</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 12pt;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">很多人把职场想得太美好，其实不然。如果你没有规划好，你就会难免遇到各种各样的问题：工作不开心；没有前进的动力；工作不是自己想像的那么好；自己的才能无法发挥；看到以前的同学待遇如何如何，便受不了刺激，急切地想跳槽；当初为了生存而找的工作，根本就不适合自己&#8230;&#8230;</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">这 是几乎所有初入职场的朋友都会面临的问题。而这些问题通常会在步入职场的1－3年之内最明显（3年之后之所以不明显，是因为你已经被现实折磨得太久了，已 经被种种不平现象同化了，因此也就习惯了。你曾经的种种抱负被现实碾得粉碎，于是，你也从一个志向远大的年轻人一下子变成了一个碌碌无为、甘于平庸、成天 为了生计而奔走的普通打工者）。如果不及早解决这些问题，那么，你就会荒废这3年的时间（有的人可能会更长），而对于一个职场新人来说，这3年至关重要， 是锻炼能力、积累资本的黄金3年！一旦错过，则要花费更多的时间，从头再来，重新弥补！更有甚者，可能一辈子都无法弥补！这绝对不是危言耸听！因此，如果 你的职场年龄还没有超过3年，恭喜你，还有改变命运的机会。而一旦超过了3年，那么，你的每一次改变，都将付出巨大的代价！</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">为 什么要清楚自己的目标？因为，有了目标，才有行动的指南。知道自己想干什么，喜欢干什么，这才是你前进的最终动力。工作不开心、动力不足、盲目跳槽的最根 本原因是职业目标不清晰。没有目标，便没有了追求，于是，所有的行动只是为了挣一口饭吃。你根本没有考虑过自己的未来应该端什么饭碗。或许你在30岁之前 还有挥霍的资本，因为年轻嘛，做什么都不怕。连广告上都说了，&#8220;30岁之前，有什么好怕的？！&#8221;而一旦过了30岁，你走的每一步都必须要慎之又慎，因为： 你要结婚、你要养活老婆孩子、你要供房贷、你要供养年迈的父母、孩子大了还要上学、父母年迈了需要照顾&#8230;&#8230;等等等等，所有的这些责任，都要你来承担。如果 没有规划，一旦出现问题，你只能自乱阵脚。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">人 生的职业发展如同品牌塑造一样，只不过你的产品就是你自己。你自己的发展目标，也就是你人生的品牌目标。有了目标，就要考虑该怎么走。每走一步，都应该离 目标更近，而不是更远。所以，你每做一个决定的时候，要衡量这个决定对不对，唯一的标准就是：它是不是能够帮助你离目标更近？如果不是，那么，赶紧住手， 因为，你走的路偏离了你的目标！再走下去，只能错得更离谱！</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">对 于人生目标，涉及到职业生涯规划的问题。这是一个老话题，很多人以为自己很了解了，其实却远不是那么回事。大家可以看一些相关书籍，但在中国，此类书籍的 最大问题就是说教性比较强，实用性非常差！很多人看了书之后依然一头雾水，不知所措，看了之后反而更糊涂。我的意见是，最好还是找一些专门的机构咨询一 下。注意：是咨询，不是测评。二者的区别在于，咨询的意义在于&#8220;为客户提供可应用性的解决方案&#8221;，而测评则仅仅局限于&#8220;帮助你认识自己&#8221;，至于怎么做，怎 样行动才能更接近自己的目标，不知道！因为测评的人都是专家，而国内的专家都是做研究的，没有实战经验，甚至对职场升迁是怎么回事都不太清楚，怎么可能指 导你做实战规划？建议大家去做一下职业生涯规划。如果现在不解决，恐怕未来3年你都会白白浪费，更有可能因此而毁了你的一生！</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 10pt; font-family: Arial;">记住：有了规划，不一定能够成功；但没有规划，一定不会成功！</strong></p><br /><br style="line-height: 18px;" /> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 10pt; font-family: Arial;">二、能力固然重要，但并不能代表全部</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 12pt;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">这 里所说的能力，是指专业技能。步入职场你会发现，能力其实并没有你想像的那么重要，它并不是是步步高升的全部资本。你会发现一个能力不太强的人做了你的上 司，只因为他在这个公司干了10年&#8212;&#8212;这说明&#8220;资历&#8221;是你高升的本钱（这种现象，在国有企业和政府机构里特别明显，因此，在国企工作的朋友和公务员同志要 注意了）；有时候你会发现能力并不怎么强，但是与老板关系非常好的人通常能够得到提拔&#8212;&#8212;这说明&#8220;关系&#8221;也是本钱。在我原先工作的公司，有两个特别明显的 例子。一个有着丰富工作经验的男士，跳槽来到公司，能力也特别强，但就是与同事处理不好关系，自认为自己非常牛，喜欢主动当别人的&#8220;导师&#8221;，动不动就对别 人的工作指手画脚，顶头上司非常讨厌他；而同时进入公司的另外一位女士，能力不是特别强，但是非常踏实、勤奋、与其他同事相处得也很好，能够顾全大局。最 后试用期结束时，那位女士得到了公司的认可，而那位男士则收到了公司的辞退通知。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">在 职场上，一定要对职场有清醒的认识，不要生活在梦幻当中，不要太理想化，不要标新立异，不要恃才傲物，不要认为有能力就可以走遍天下。专业技能固然重要， 但是职场发展看的是一个人的综合素质。综合素质高的人，才是职场发展的&#8220;潜力股&#8221;。这些综合素质，包括沟通能力、人际关系能力、团队合作能力、管理能力、 工作态度及敬业精神等各种&#8220;软实力&#8221;。对于有些朋友而言，可能会对这些&#8220;软实力&#8221;不屑一顾。很多人会说，如果老板喜欢爱拍马屁的人，难道我就要委屈自己， 学着去拍马屁？很不幸，我会告诉你，答案是肯定的，你一定要学会拍马屁，否则吃亏的是自己。但要声明的是，我不是教你诈。中国有句成语，叫外圆内方，用在 人际交往上，就是说你与人相处要学会妥善处理各种关系，但不可因此而失去了内心的准则，否则就变质了。尤其在中国这种注重人情的社会，这种人际交往的能力 一定要好好练练。如果有时间，看一下《厚黑学》，了解一下社会现实，切忌不可因此而迷失了自己。</span></p><br /><br style="line-height: 18px;" /> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 10pt; font-family: Arial;">三、要有足够的&#8220;亮剑&#8221;资本</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 12pt;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">有 的大学生经常会跟我说，我毕业之后一定要找到一份月薪多少多少的工作，争取做到什么什么职位。这时候我总是会耐心听完他们的&#8220;远大蓝图&#8221;，然后问一句： &#8220;你凭什么达到你的目标？你的资本是什么？&#8221;然后他就会哑口无言。我相信读过这篇文章的人也会和这位大学生一样，有着自己的伟大抱负，但是大学四年下来， 你有没有想到，要实现这些目标，你的资本是什么？对于很多已经身在职场的朋友而言，你晋升的资本又是什么？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">人 生在发展过程中，很多时候都需要毫不犹豫地向别人展示自己的实力，要敢于展示，善于展示，这就是&#8220;亮剑&#8221;。因为这年头，酒香也怕巷子深，是金子未必会发 光。相反，发光的倒是那些碎玻璃、烂瓶子。中国什么都缺，就是不缺人。茫茫人海，如果你一直都谦虚地默默无闻，那么，你就大错特错了。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">既 然具备了&#8220;亮剑&#8221;的意识，那么，下一步你就要考虑到亮什么剑：我到底拿什么资本给人家看？对于职场上的朋友而言，你&#8220;亮剑&#8221;的资本又在哪里？你的业绩提升 了吗？你的能力提升了吗？你在一年内看过多少本对自己的职业有益的书籍？你参加过几次培训班来为自己充电？如果没有，你又凭什么让老板为你加工资？靠抱 怨？你肯定会提前被职场淘汰出局！</span></p><br /><br style="line-height: 18px;" /> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 10pt; font-family: Arial;">四、慎重对待第一份工作</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 12pt;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">这一观点，对于大学生来说，更有意义。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">现在整个社会、媒体、专家等等各种单位都一直在鼓吹&#8220;先就业，再择业&#8221;。这种论调不是今年就有，而是多好多年前就出现了，并且屡屡出现，不绝于耳。相信当年我们大学毕业时候，也会有很多人相信了这一点吧？管它呢，骑驴找马，先找份工作挣钱填饱肚子再说！</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">但 是根据本人自身的经验及职场发展的现实情况来看，本人绝对不赞同这种说法。相信现在在职场上发展不顺的朋友，多半也和第一份工作有关系吧？俗话说，&#8220;男怕 入错行，女怕嫁错郎。&#8221;第一步错了，以后就会经常犯错。正所谓一步错，步步错。为什么第一分工作这么重要呢？原因有三：</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 12pt;"><br /></span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">1、 先入为主的观念影响。具体是指，先听进去的话或先获得的印象往往在头脑中占有主导地位，以后再遇到不同的意见时，就不容易接受。举个最简单的例子：在你的 头脑印象中，诺基亚已经是手机的代名词。如果有一天诺基亚生产出了一种&#8220;诺基亚牌电脑&#8221;，你的心里是什么感觉？非常不对劲对不对？这主是先入为主现象。我 原先有一个同事，曾经在海尔工作过，她用的是海尔的手机，功能也非常不错，但她总是说要换一部手机，我问她原因，她说，兜里装着海尔的手机，总感觉像装了 一个大冰箱，非常不舒服。为什么？先入为主呗！不要小看这一现象，其实对人的潜意识影响非常大。海尔的手机和电脑等IT产品卖得不好，相当一部分是因为先 入为主：大家普遍认为海尔是家电的代名词，而不是IT的代名词。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">对 于求职的大学生来说，这一观念同样会影响你以后的发展。你的第一份工作会对你以后的工作产生影响，你跳槽时，你的新雇主也会通过你的第一份工作经验来判断 你是否能够胜任这份工作。曾经有一个大学生，毕业之后想做策划，就找了一家广告公司。刚进公司时，因为文笔不错，被安排到了文案的位子上。而与他同时进去 的另外一个人，恰恰因为文笔不好而被安排到了策划的位子上。后来她屡次想转行做策划，但都是因为前一份工作经验的影响，而始终没有得到转行的机会。</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 12pt;"><br /></span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">2、 职场中不允许从头再来。如果公司招聘的是有几年工作经验的老员工，一定要求是&#8220;相关经验&#8221;！这一点至关重要！因为这样的员工一般不需要培训，可以直接上 岗，会很快为公司带来最大的效益。如果是工作几年以后再打算转行的应聘人员，一般不会受到重视，一是不会给公司直接带来效益，二是培训起来也比较困难，思 维已经固化。与其这样，倒不如招一名应届生，白纸一张，可塑性强，发展起来潜力更大。所以，一旦有了工作经验之后，再想转行从头再来，难度相当大。除非你 认识公司的高层领导，可以得到一个机会，否则，很难。</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 12pt;"><br /></span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">3、时间成本不允许。步入职场的前三年，是一个人职业成长的最重要、最关键的时期。如果你这时候还把工作的重点放在骑驴找马式的转行上，则会浪费你最宝贵的青春，你的成长也因此比其他人慢一步，而很多晋升的机会将因此而失去。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">所以，对待第一份工作，一定要慎重。找工作就像结婚，情愿不结，绝不能乱结。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">如果现在你刚刚步入职场还不到3年，劝你趁早做一个职业规划，亡羊补牢，尤未为晚。一旦你结婚了买房子了，你再想弥补都已经晚了！</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 12pt;"><br /></span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 10pt; font-family: Arial;">五、要保持一种&#8220;空杯心态&#8221;</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-size: 12pt;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-size: 10pt; font-family: Arial;">给大家讲一个故事。</span></p> <hr style="border-width: 0px 0px 1px; border-bottom: 1px solid #e7f0f5; line-height: 18px; height: 0px;" noshade="noshade" size="1" /></span><span style="line-height: 18px; font-family: Arial,Helvetica,sans-serif; color: #333333; font-size: 12pt;"> </span><span style="line-height: 18px; font-family: Arial; color: #333333; font-size: 10pt;">古 时候有一个佛学造诣很深的人，听说某个寺庙里有位德高望重的老禅师，便去拜访。老禅师的徒弟接待他时，他态度傲慢，心想：我是佛学造诣很深的人，你算老 几？后来老禅师又十分恭敬地接待了他，并为他沏茶。可在倒水时，明明杯子已经满了，老禅师还不停地倒。他不解地问：&#8220;大师，为什么杯子已经满了，还要往里 倒？&#8221;大师说：&#8220;是啊，既然已满了，干嘛还要倒呢？&#8221;   <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">禅 师的意思是，既然你已经很有学问了，干嘛还要到我这里求教？这就是&#8220;空杯心态&#8221;的故事哲理。它最直接的含义就是一个装满水的杯子很难接纳新东西，要将心里 的&#8220;杯子&#8221;倒空，将自己所重视、在乎的很多东西以及曾经辉煌的过去从心态上彻底了结清空，只有将心倒空了，才会有外在的松手，才能拥有更大的成功。这是每 一个想在职场发展的人所必须拥有的最重要的心态。它告诉我们一个道理：做事的前提是先要有好心态。如果想学到更多的学问，先要把自己想象成&#8220;一个空着的杯 子&#8221;，而不是骄傲自满。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我 见过很多的大学毕业生，刚进入公司时常常处处吹牛，说自己在学校如何如何，本来可以找到更好的工作，迫不得已才来到了这里等等之类的话，好像这家公司委屈 了自己。在这里提醒一下那些即将步入职场的大学生：这种心态千万要不得！不要认为自己很牛。还是那句你不爱听的话：中国什么都缺，就是不缺人！话又说回 来，你要是这么牛，为什么不像比尔?盖茨、戴尔、乔布斯那样，大学没毕业就退学去创办一家世界级的大企业？火车不是推的，牛皮不是吹的。你要是有本事，就 用事实证明给人家看，而不是成天抱怨！</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">对 于身在职场的朋友而言，这一心态同样重要。中国有一个词，叫&#8220;虚怀若谷&#8221;。我们都知道，优秀的人有极高的素养，甚至是虚怀若谷，他们都有一个能包容一切的 胸怀，有了这样的胸怀，你在职场上就会获得别人的尊重，就会获得更多的发展机会。类似的词还有&#8220;大智若愚&#8221;&#8220;大巧若拙&#8221;等等，不多说，自己去体会。</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><br /></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-family: Arial; font-size: 10pt;">六、要懂一点做人的常识</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">职场就像一个大熔炉。在职场中，不仅仅是要挣一碗饭吃，更重要的是学会做人的道理。如果连最起码的道理都不懂，你不仅得不到别人的尊重，更会失去更多的发展机会。因为，在中国，人际关系也是生产力。中国有句古话：得道多助，失道寡助。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我见过很多人，虽然已经工作多年，但对于做人，却连一点最基本的常识都不懂。做人的道理万万千，但其中最重要的，莫过于以下三条：</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><br /></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">1、 严于律己，宽以待人。你和同事之间闹过不愉快吗？在批判别人的同时，你是否深刻地反省过自己？工作出现问题的时候，你是否把责任往别人身上推过？有人向你 提出不同意见时，你是否能够坦然接受？面对别人的指责，你是否曾经微笑着予以回应？人人都有自我防备的本能，这一点无可厚非。但在防备的同时，你是否敞开 胸怀接纳过别人？&#8220;忍一分风平浪静，退一步海阔天空。&#8221;出现问题时，如果大家都能够怀着一种宽容的心态，又有什么问题会出现呢？很多人不知道&#8220;严于律己， 宽以待人&#8221;的道理。正是因为很多人不知道，于是懂得这个道理的人就很容易走向成功。宽大的胸怀会让你积累很多的人脉，得到大家的尊重；当你需要帮助时，大 家也乐意伸手。感激伤害你的人，因为他磨练了你的心态；感激绊倒你的人，因为他强化了你的意志；感激欺骗你的人，因为他增进了你的智慧；感激蔑视你的人， 因为他觉醒了你的自尊；感激遗弃你的人，因为他教会了你如何独立。对待每一个人，都要怀着宽容和感恩的心。正如李嘉诚先生所言，&#8220;凡事都留个余地，因为人 是人，人不是神，不免有错处，可以原谅人的地方，就原谅人。&#8221;</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><br /></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">2、 学会倾听。生活中我们往往会主动寻找倾诉对象，做一个倾诉者，而回避做一个倾听者。在人与人的交往中，倾听是一个不可缺少的方面，有时它甚至比交流还要重 要。学会倾听，能修身养性，陶冶性情；学会倾听，能博采众长，弥补自己考虑问题的不足；学会倾听，能使人萌发灵感，触类旁通；学会倾听，能养成尊重他人的 良好品质，创造一个良好的人文环境；学会倾听，能体会一种默默无语的关心和体贴，赢得亲情、爱情和友情；学会倾听，还能在矛盾激化时，让对方从另一个角度 重新认识自己，打开僵持的局面&#8230;&#8230;</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">学会倾听就是学会一种美德，一种修养，一种气度。切忌中途插话或打断他人，否则会被视为不礼貌和缺乏修养。一个谦虚好学的人，一个懂得善待他人的人，一个会反思的人，永远懂得倾听！无论什么时候，倾听都显示出一个人的职业素养。</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><br /></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">3、 诚实守信。诚实是力量的一种象征，它显示着一个人的高度自重和内心的安全感与尊严感。社会中固然处处充满了相互利用、利益至上的现象，在这种情况下，诚实 守信就变成一种无价的资产。诚实守信，才能建立良好的人际关系，打下牢靠的事业基础，取得坚实的人生业绩。而那种两面三刀、当面一套背后一套的人，固然可 以占一点小便宜，但那种短视的行为，会让你慢慢失去很多东西。学会尊重别人，信守承诺，尽量去帮助别人，宽待他人，都可以提升你的诚信。要想成就大事，诚 实守信的传统美德永远不会过时。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">总之一句话：认认真真做事，踏踏实实做人！</span></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><br /></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-family: Arial; font-size: 10pt;">七、要学会遵守游戏规则</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我 为什么在文章一开头就提醒&#8220;愤青&#8221;或者&#8220;类愤青&#8221;们不要看这篇文章？因为他们多半是放荡不羁、不会遵守游戏规则的主儿！很多人都会感觉到，在职场上发展， 不仅会受到各种约束，而且处处都充满了不公平现象。比如：上班迟到老板会扣你工资，但你加班的时候却从来没有拿过加班工资；你立功的时候没有受到过表彰， 一旦犯错，老板却指着鼻子骂个不停。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">在 这个世界上，不要奢求公平。那只是一种乌托邦式的理想，从来都不存在于现实社会中。员工和老板之间的关系，就好像是一场游戏。是游戏就会有游戏规划，否 则，游戏就玩不下去。但是，游戏规则是谁制定的呢？当然是老板，各种利益也偏向老板！身在职场的你，一开始肯定看不惯这种现象，但你一定要学会慢慢接受这 种游戏规则。不要试图改变这种规则，因为在老板面前，你没有太多的话语权（更有许多多年以来自然形成的潜规则，你更是无法改变）。说得再难听些，你只是一 个打工的，混口饭吃，给你吃就不错了，还嫌饭凉？如果不想做，可以离开。还是那句话：中国什么都缺，就是不缺人。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">记住这句话：&#8220;如果你不是游戏规则的制定者，你的选择只有两条：要么屈从，要么离开！&#8221;</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><br /></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-family: Arial; font-size: 10pt;">八、行动远比说话更重要，空谈家绝不是好的实干家</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">看到这里，大家对以上的内容大概有三种反应：</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">1）、感觉非常有道理，会认真反思，积极行动；</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">2）、这些道理不用你说我也懂，纯粹是&#8220;废话&#8221;；</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">3）、感觉道理都懂，但心生疑问：真正做到的又有几个？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">如 果你是第一种反应，我衷心地祝愿你通过努力获得成功；如果你是第二种反应，我希望有机会能够聆听你的高见，因为你把道理都看&#8220;破&#8221;了；如果你是第三种反 应，我希望你能够积极行动起来。有时候之所以结果未如我们预料的那样，不是因为我们不懂，而是因为我们说得太多，而行动得太少。&#8220;执行力&#8221;不仅是企业生存 面临的问题，同样也是个人发展必须解决的问题。要想成功，必须从现在就开始行动。正如IBM的广告所言：&#8220;停止空谈，开始行动！&#8221;</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><br /></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px; font-family: Arial; font-size: 10pt;">九、机会只垂青有准备的人</strong></p><p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><strong style="line-height: 18px;"><br /></strong></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">无论你再怎么抱怨，再怎么不开心，饭还是要吃的，觉还是要睡的，工作还是要做的，未来的事情永远只属于自己的。买房子也好，娶老婆也罢，压力只有自己扛，老 板不会为你操任何心。与其有时间去抱怨，但不如踏踏实实静下心来，好好提升自己的基本功，用事实证明自己的本事，让别人对你刮目相看，万不可因为自己的书 生意气而自做一个自毁前程的&#8220;愤青&#8221;。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">当然，你的准备是多方面的，除了专业技能外，其他的辅助技能也是非常必要的，比如沟通能力、人际关系处理能力、管理能力等等。当然，更重要的是要为自己的未 来做一个规划，清楚地知道自己的目标是什么，应该怎么努力才能实现。适当的时候也要充充电，不要舍不得那半个月的工资，这也算是为自己的未来进行投资，有 什么舍不得的呢？如果你现在不学会&#8220;舍&#8221;，以后将永远也&#8220;得&#8221;不到。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">有 时候，你之所以发展得不好，不是因为没有机遇，而是因为你没有准备好，导致机遇与你擦肩而过。这个社会就是这样，再怎么不合理，再怎么不公平，但是发展机 遇是时时都会面临的，只看你有没有准备好。你要是真的练就了一身令人刮目相看的真本事，说不定明天就有人请你做某世界500强的总裁也不一定呢。</span><br style="line-height: 18px;" />&nbsp;</p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">李嘉诚先生曾经写了一首诗激励他的员工，发人深思，读了之后，感慨颇多。我把它放在这里，希望与大家共勉！</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">当你们梦想伟大成功的时候，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">你有没有刻苦的准备？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">当你们有野心做领袖的时候，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">你有没有服务于人的谦恭？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我们常常都想有所获得，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">但我们有没有付出的情操？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我们都希望别人听到自己的说话，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我们有没有耐性聆听别人？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">每一个人都希望自己快乐，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我们对失落、悲伤的人有没有怜悯鲜花？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">每一个人都希望站在人前，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">但我们是否知道什么时候甘为人后？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">你们都知道自己追求什么，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">你们知道自己需要什么吗？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我们常常只希望改变别人，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">我们知道什么时候改变自己吗？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">每一个人都懂得批判别人，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">但不是每一个人都知道怎样自我反省。</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;">&nbsp;</p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">大家都看重面子，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">大家都希望拥有财富，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">但你知道财富的意义吗？</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">各位同学，相信你们都有各种激情，</span></p> <p style="padding: 0px; line-height: 18px; text-indent: 0px; margin: 0px; font-family: Arial,Helvetica,sans-serif;"><span style="font-family: Arial; font-size: 10pt;">但你知不知道什么是爱？</span></p> <div></div></span></span></div><img src ="http://www.cppblog.com/finehai/aggbug/173042.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-28 14:50 <a href="http://www.cppblog.com/finehai/archive/2012/04/28/173042.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】谨献给嵌入式初学者</title><link>http://www.cppblog.com/finehai/archive/2012/04/24/172595.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 24 Apr 2012 06:09:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/24/172595.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172595.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/24/172595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172595.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172595.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt;"> </span><div><p><span style="font-size: 12pt;">谨献给为了知识执着的嵌入式初学者，欢迎高手补充讨论 </span></p> <p><span style="font-size: 12pt;">实践当然是最锻炼人的方式，但是我想在校生很少有这样的机会，别说本科生，硕士生也未必有条件。所以我想学习嵌入式要从个人的知识背景和现实条件出发。订立合适的阶段目标，在允许的条件下多动手多思考。</span></p> <p><span style="font-size: 12pt;">一般情况下对于硬件设备是比较短缺的。但是可以从软件方面和嵌入式系统开发模式上下功夫，提醒大家一 点，嵌入式系统开发设计的内容知识很多，所以大家不要乱，在了解嵌入式系统开发的体系结构后，一步一步的下手，最容易上手的是linux下的C，比如 ucos（有开放源代码），虽然可能无法在硬件上仿真，但也不必着急。wince，palmos上手都很容易。无论对于初学者还是自以为是高手的人来说， 编程水平（这可不受硬件条件限制）绝对是没有止境的，有了较高的编程水平（嵌入式主要是C,当然OO的几种语言c++,java是发展趋势），等到有机会 的时候及时的补充硬件知识，会很快的成为高手。</span></p> <p><span style="font-size: 12pt;">还有，一定记住，学习嵌入式，&#8221;要想办法，不要找理由&#8220;。当年在dos下用tc编程时的条件，现在回想起来建筑就是奇迹。</span></p> <p><span style="font-size: 12pt;">我推荐一条发展道路吧，仅供参考，</span></p> <p><span style="font-size: 12pt;">1、C开发经验</span><br /><span style="font-size: 12pt;">条件：linux（这都有吧）</span><br /><span style="font-size: 12pt;">方法：随便，主要是掌握ansiC编程（不包括gtk,qt等图形可视化开发）</span></p> <p><span style="font-size: 12pt;">2、网络、操作系统、体系结构</span><br /><span style="font-size: 12pt;">条件：linux，各种书，算法、例程。</span><br /><span style="font-size: 12pt;">方法：通过C编程实现简单的网络等知识的算法和过程。</span></p> <p><span style="font-size: 12pt;">3、嵌入式系统概念</span><br /><span style="font-size: 12pt;">条件：各个嵌入式网站，讨论组，书籍</span><br /><span style="font-size: 12pt;">方法：少提问（尤其是等着天上掉馅饼，这主要是防止增长惰性，也解决不了实际问题），多思考。</span></p> <p><span style="font-size: 12pt;">4、嵌入式开发实践</span><br /><span style="font-size: 12pt;">条件：各种嵌入式系统开发工具的demo版（或者D版，如果有的话），包括编译器，仿真器。可以找高手们要，也可以下载。</span><br /><span style="font-size: 12pt;">方 法：这里有两个分支，一个是基于mcu/dsp的嵌入式系统开发，一个是象palmos,wince,ucos等rtos下的应用软件开发。对硬件感兴 趣，想成为真正高手的由第一个分支入手，以后进入第二个分支；如果十分厌烦硬件，只想停留在软件开发上的，可以只由第二个分支入手，以后就和pc上的开发 没有什么本质上的区别了，找份不错的工作应该没问题，可以不用进行下面的步骤了，感兴趣可以参考第6条。</span></p> <p><span style="font-size: 12pt;">5、硬件开发</span><br /><span style="font-size: 12pt;">条件：各种嵌入式芯片、存储器等电路器件，protel99等电路设计软件，电路板制作。</span></p> <p><span style="font-size: 12pt;">方法：这时候该有开发条件了，最起码是51系列，这个比较方便。电路的设计内容较多，不过看起来吓人，实际上比软件要简单的多。只要下功夫，实践会告诉你一切。</span><br /><span style="font-size: 12pt;">6、硬件工程/软件工程/项目管理</span><br /><span style="font-size: 12pt;">条件： 各个芯片详细资料和使用经验，软件工程知识，项目管理知识，培训，大型项目参与经验</span><br /><span style="font-size: 12pt;">方法：已经是高手了，但是学无止境，沾沾自喜于已有的知识是致命的。那个下一步。。。，你该是管理者了。</span></p> <p>&nbsp;</p><p><span style="font-size: 12pt;">补充几点. </span></p> <p><span style="font-size: 12pt;">要想成为高手中的高手,最好从钻研如下领域修炼:</span><br /><span style="font-size: 12pt;">1,分析一种RTOS的源代码--UCOS最容易;</span><br /><span style="font-size: 12pt;">2,分析一种通讯协议栈的实现方式--TCP/IP最实用;</span><br /><span style="font-size: 12pt;">3,精通一种DSP的开发集成环境--TI CCS2.1最优秀,精华在其内带的RTOS;</span><br /><span style="font-size: 12pt;">4,精通一种单片机的开发集成环境--keil C最经典;</span><br /><span style="font-size: 12pt;">5,精通一种MCU的开发集成环境--ADS 1.2最流行;</span></p><p><br /><span style="font-size: 12pt;">要想成为大师级人物再从如下领域开始修炼:</span><br /><span style="font-size: 12pt;">1,精通一种系统建模语言和工具--Telelogic tau SDL/UML suit最经典;</span><br /><span style="font-size: 12pt;">2,精通一种算法仿真工具--Matlab simulink 最便宜;</span><br /><span style="font-size: 12pt;">要想检验一下自己是否到达了至尊级人物，可以做如下的事：</span><br /><span style="font-size: 12pt;">动手搭建一套红外或者蓝牙通讯原型系统，模拟前端可以用现成的，基带用DSP，主控用个32BMCU，DSP和协议软件自己写。当然不可能做全，做个子集就可以了。</span><br /><span style="font-size: 12pt;">如果能到这个地步，打住吧，该改行去做市场了。做个一、二年市场，你不自己去创个业就太浪费了。</span></p></div><img src ="http://www.cppblog.com/finehai/aggbug/172595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-24 14:09 <a href="http://www.cppblog.com/finehai/archive/2012/04/24/172595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FTP工作原理 </title><link>http://www.cppblog.com/finehai/archive/2012/04/24/172593.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 24 Apr 2012 06:05:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/24/172593.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172593.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/24/172593.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172593.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172593.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt;"> </span><div><p><span style="font-size: 12pt;"><br /></span></p><p><span style="font-size: 12pt;">FTP Transfer Protocol 件传输协议的缩写,在RFC 959中具体说明。</span></p> <p><span style="font-size: 12pt;">FTP会话时包含了两个通道，一个叫控制通道，一个叫数据通道。</span></p><p><span style="font-size: 12pt;"><br /></span></p> <p><strong style="font-size: 12pt;">控制通道</strong>：<span style="font-size: 12pt;">控制通道是和FTP服务器进行沟通的通道，连接FTP，发送FTP指令都是通过控制通道来完成的。</span></p> <p><strong style="font-size: 12pt;">数据通道</strong>：<span style="font-size: 12pt;">数据通道是和FTP服务器进行文件传输或者列表的通道。</span></p><p><span style="font-size: 12pt;"><br /></span></p> <p><span style="font-size: 12pt;">FTP协议中，控制连接均有客户端发起，而数据连接有两种工作方式：PORT方式和PASV方式</span></p> <p> </p><dl><dt><strong style="font-size: 12pt;">PORT模式(主动方式)</strong>  </dt><dd> <p><span style="font-size: 12pt;">FTP 客户端首先和FTP Server的TCP  21端口建立连接，通过这个通道发送命令，客户端需要接收数据的时候在这个通道上发送PORT命令。  PORT命令包含了客户端用什么端口(一个大于1024的端口)接收数据。在传送数据的时候，服务器端通过自己的TCP 20端口发送数据。 FTP  server必须和客户端建立一个新的连接用来传送数据。</span></p></dd><dt><br /></dt><dt><strong style="font-size: 12pt;">PASV模式(被动方式)</strong>  </dt><dd> <p><span style="font-size: 12pt;">在建立控制通道的时候和PORT模式类似，当客户端通过这个通道发送PASV 命令的时候，FTP  server打开一个位于1024和5000之间的随机端口并且通知客户端在这个端口上传送数据的请求，然后FTP server  将通过这个端口进行数据的传送，这个时候FTP server不再需要建立一个新的和客户端之间的连接传送数据。</span></p></dd><dt><br /></dt></dl>  <p><span style="font-size: 12pt;">如果从C/S模型这个角度来说，PORT对于服务器来说是OUTBOUND，而PASV模式对于服务器是INBOUND，这一点请特别注意，尤其是在使用防火墙的企业里，这一点非常关键，如果设置错了，那么客户将无法连接。</span></p></div><img src ="http://www.cppblog.com/finehai/aggbug/172593.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-24 14:05 <a href="http://www.cppblog.com/finehai/archive/2012/04/24/172593.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习嵌入式Linux的笔记和体会</title><link>http://www.cppblog.com/finehai/archive/2012/04/24/172592.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 24 Apr 2012 06:01:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/24/172592.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172592.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/24/172592.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172592.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172592.html</trackback:ping><description><![CDATA[<span style="font-size: 14pt;"> </span><div><span style="font-size: 12pt;">一个典型的桌面Linux系统包括3个主要的软件层---linux内核、C库和应用程序代码。</span><span style="font-size: 12pt;">内核是唯一可以完全控制硬件的层，内核驱动程序代表应用程序与硬件之间进行会话。内核之上是C库，负责把POSIX API转换为内核可以识别的形式，然后调用内核，从应用程序向内核传递参数。应用程序依靠驱动内核来完成特定的任务。 </span><br /><br /><span style="font-size: 12pt;">在设计嵌入式应用的时候，可以不按照这种层次，应用程序越过C库直接和内核会话，或者把应用和内核捆绑在一起，甚至可以把应用写为内核的一个线程，在内核中运行，虽然这样在移植上带来了困难，但考虑嵌入式系统对尺寸要求小的特点，是完全可行的。不过我们使用三层软件结构的模式来学习嵌入式linux将会是我们认识更清晰，简单可行并使应用具有弹性。 </span><br /><br /><strong style="font-size: 12pt;">快速入门</strong><br style="font-size: 12pt;" /><br /><span style="font-size: 12pt;">最简单的建立嵌入式Linux应用的方法就是从我们使用的桌面Linux入手，安装一个喜爱的版本，把我们的某个应用作为初始化的一部分，框架就算完成了。</span><br /><br /><span style="font-size: 12pt;">当然，嵌入式linux应用远比我们的桌面版本功能简单专一，它也许就是一个用于足彩的终端机，或是一个数码音频播放器，这些系统除了使用嵌入式CPU外，仅仅再需要一个串口，网口等少量的输入输出接口就可以完成它们特定的应用了。 </span><br /><br /><span style="font-size: 12pt;">在软件上，它可以按照三层的概念由内核装载器，定制的内核和较少的为特定任务设计的静态连接的应用程序组成。之所以使用静态连接的应用程序，是因为少量的静态连接程序所要的存储空间，比同样数量的动态连接的程序所占的空间小，这个平衡点需要我们在实际开发中去获取。也许你正在设计的是个PDA，它的应用程序较多，那么你很可能就要使用动态连接程序来减少存储空间。在你的/bin或者/sbin目录下，用厂列表看看bash,ifconfig,vi...，也许只用几十K，当你运行 ldd /bin/bash  时，你会看到它们都和好几个库文件相连。好了，这样看来，我们得把PC想像成一个嵌入式硬件平台，再重新制作一个特定功能的嵌入式linux。 </span><br /><br /><strong style="font-size: 12pt;">基础知识</strong><br /><br style="font-size: 12pt;" /><span style="font-size: 12pt;"> </span><p style="font-size: 12pt;">再进行实际操作之前，先来搞清楚几个基础知识。 <br /></p><p style="font-size: 12pt;"><br /></p><p style="font-size: 12pt;">内核装载器Loader，它的作用是把内核从外部存储器，移动到内存中。它只作这个事情，一旦完成了调入内核的工作，Loader就跳转到内核位置开始执行。不同架构有不同的 Loader，在x86结构的PC上，通常使用的loader有LILO,GRUB,syslinux,syslinux在嵌入式linux中也同样工 作。其他非x86架构的应用中，你必须使用专门的loader，或者自己编写loader来装入内核。也有不使用loader的情况，系统加电以后，内核 直接从烧录有映象的Flash上开始执行。 <br /></p><p style="font-size: 12pt;"><br /></p><p style="font-size: 12pt;">内核，一旦内核开始执行，它将通过驱动程序初始化所有硬件，这可以从我们的pc机监视器的输出看出 来，每个驱动程序都打印一些有关它的信息。初始化完成后，计算机就准备运行嵌入式应用。也许一个，也许是多个应用程序组成了嵌入式应用，但通常首先调用的 是init(通过loader 向核心传入init=/program  可以定制首先运行的程序)。桌面linux中，init会读取/etc/inittab文件，来决定执行级别和哪些脚本和命令。嵌入式应用中，可以根据实 际的情况决定是否使用标准的init执行方式，也许这个init是个静态程序，它能够完成我们的嵌入应用的特定任务，那完全不用考虑inittab了。 <br /></p><p style="font-size: 12pt;"><br /></p><p style="font-size: 12pt;">initrd 文件系统，initrd以一种把内核从存储介质装入到内存的相同的机制来装入一个小型文件系统。这个文件系统最好是以压缩的方式存储在介质上的，解压缩到 RAM盘上。通过使用initrd,包含有核心驱动和启动脚本的小文件系统，就可以直接从介质上和内核一起启动起来，内核届压缩这个文件系统，并执行这个 文件系统上叫做/linuxrc的脚本文件，这个脚本通常会把启动过程中所需要的驱动程序装入。脚本退出以后，initrd文件系统也卸下了，启动过程进 入真正初始化过程。对于嵌入式来讲，可以将需要的应用软件都运行在这个initrd文件系统上，只要/linxrc文件不结束，内核启动过程的其他部分就不会继续。&nbsp;</p><p style="font-size: 12pt;"><br />做个试验： <br />cp /boot/initrd-2.4.20.img /tmp <br />cd /tmp <br />mv initrd-2.4.2-.img initrd.img.gz <br />gunzip initrd.img.gz <br />mount -o loop initrd.img /mnt <br />cd /mnt <br />ls <br />cat linuxrc 可以看到里面执行了加载了两个模块的操作，你在启动linxu的时候会看见屏幕打印信息。 <br /></p><p style="font-size: 12pt;"><br /></p><p style="font-size: 12pt;"><br /><strong>入门试验，制作一个简单的应用</strong><br /><br />我们使用一张软盘启动一台假象的只有一个串口，键盘输入，显示输出的x86架构的linux系统，执行的特定应用就是运行minicom，通过串口拨号。需 要软件: minicom-xx.src.tar.gz 和 syslinux-xx.tar.gz，xx代表版本号  ，开始之前，在主目录建立一个目录，来释放这两个软件包：&nbsp;</p><p style="font-size: 12pt;"><br />cd <br />mkdir -p project/minilinux <br />cd project/minilinux <br />tar zxvf minicom-xx.src.tar.gz <br />tar zxvf syslinux-xx.tar.gz <br /><br />1、裁减linux内核(需要系统安装内核文件包) <br /><br />配置内核的时候，我们需要选择这些：摸块编入内核，386处理器、物理内存off、支持ELF、标准PC软盘、支持RAM盘(4096)、支持 initial RAM disk (initrd)、虚你终端、虚拟终端控制台、标准串口、ext2文件系统、控制台驱动，VGA text  console、DOS FAT、MSDOS文件系统，其他的都可以不要，这样内核编出来较小。&nbsp;</p><p style="font-size: 12pt;"><br />步骤: <br />cd /usr/src/linux <br />make mrproper <br />make xconfig <br />make dep &amp;&amp; make bzImage <br />得到 /usr/src/linux/arch/i386/boot/目录的内核文件bzIamge。 <br /><br />2、编译一个静态的minicom，把它作为将来的linuxrc&nbsp;</p><p style="font-size: 12pt;"><br />cd minicom-xx/src <br />vi Makefile <br />修改下面这行 <br />minicom: $(minicom_OBJECTS) $(minicom_DEPENDENCIES) <br />rm -f minicom 下面的行加上 -static，连接为静态程序 <br />(LINK) -static $(minicom_LDFLAGS) $(minicom_OBJECTS) $(minicom_LDADD) $(LIBS) <br /><br />vi minicom.c <br />找到 if (real_uid==0 &amp;&amp; dosetup==0 ) 删除这个判断条件语句，主要是用于权限判断的，因为这个嵌入应用不关注权限问题，否则会出错。 <br />make <br />得到可执行程序，用ldd 检查一下是不是静态程序。 <br /><br />3、准备initrd压缩文件image.gz&nbsp;</p><p style="font-size: 12pt;"><br />dd if=/dev/zero of=image bs=1k count=4096 <br />losetup /dev/loop0 image <br />mke2fs -m 0 /dev/loop0 <br />mounmt -t ext2 /dev/loop0 /mnt/ <br />mkdir -p /mnt/dev <br />mkdir -p /mnt/usr/share/terminfo/l/ <br />cd /dev <br />cp -a consle null tty tty0 zero mem /mnt/dev <br />cp -P /usr/share/terminfo/l/linux /mnt/usr/share/terminfo/l/linux <br />cp ~/project/minilinux/mincom/src/minicom /mnt/linuxrc <br />umount /mnt <br />losetup -d /dev/loop0 <br />sync <br />gzip -9 image <br /></p><p style="font-size: 12pt;"><br /></p><p style="font-size: 12pt;"><br />4、制作软盘引导，并拷贝文件 bzimage image.gz 到软盘 <br /><br />A.使用grub <br />fdformat /dev/fd0 <br />mke2fs /dev/fd0 <br />mount /mnt/fd0 /mnt/floppy <br />mkdir -p /mnt/floppy/boot/grub <br />cp /boot/grub/stage1 /boot/grub/stage2 /mnt/floppy/boot/grub <br />执行 grub，在软盘上创建引导 <br />grub &gt; root (fd0) <br />grub &gt; setup (fd0) <br />grub &gt; quit <br /><br />cp /usr/src/linux/arch/i386/boot/bzImge /mnt/floppy <br />cp ~/porject/minilinux/image.gz /mnt/floppy <br /><br />编辑 /mnt/floppy/boot/grub/grub.conf <br />default =0 <br />timeout-=10 <br />title minilinux <br />root (fd0) <br />kernel /bzImage <br />initrd /image.gz <br /><br />卸下软盘 <br />umount /mnt/floppy <br /><br /><br />B. 使用syslinux <br />fdformat /dev/fd0 <br />mkfs.msdos /dev/fd0 <br />mount -t msdos /dev/fd0 /mnt/floppy <br /><br />cp /usr/src/linux/arch/i386/boot/bzImge /mnt/floppy <br />cp ~/porject/minilinux/image.gz /mnt/floppy <br /><br />cp syslinux-xx/ldlinxu.sys /mnt/floppy <br />cat &gt; /mnt/floppy/syslinux.cfg <br />LABEL linux <br />KERNEL bzimage <br />APPEND initrd=image.gz <br /><br />umont /mnt/floppy <br />syslinux-xx/syslinux /dev/fd0 <br />sync <br /><br />5、用软盘启动计算机，如果幸运，minicom的运行画面出现在屏幕上。 <br /><br />到此，我们的单应用嵌入式linux做好了，但它还很简陋，没有什么实际用途，但通过这个实验，可以了解嵌入式系统的大致结构和开发过程。在进行实际的嵌入 式开发时，通常要在PC机上借助嵌入式linux开发工具包，如：uclinux,bluecat等，对相应的硬件平台(目标机)进行软件编写编译，调试成功后，将内核及应用程序写入到目标机的存储器中，从而完成整个应用。</p></div><img src ="http://www.cppblog.com/finehai/aggbug/172592.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-24 14:01 <a href="http://www.cppblog.com/finehai/archive/2012/04/24/172592.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux内核网络栈</title><link>http://www.cppblog.com/finehai/archive/2012/04/24/172589.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 24 Apr 2012 05:50:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/24/172589.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172589.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/24/172589.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172589.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172589.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt;"> </span><div><div> <div><strong style="font-size: 14pt;"><br /><div><span style="font-size: 14pt;"><br />一、linux内核网络栈代码的准备知识<br /><br /></span></div><br /></strong><strong style="font-size: 12pt;">1.</strong><span style="font-size: 12pt;"> </span><strong style="font-size: 12pt;">linux内核ipv4网络部分分层结构</strong><span style="font-size: 12pt;">：</span></div> <div>&nbsp;</div> <div><br /><strong style="font-size: 12pt;">BSD socket层： </strong>这一部分处理BSD socket相关操作，每个socket在内核中以struct socket结构体现。这一部分的文件</div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">主要有：/net/socket.c /net/protocols.c etc</span><br /><br /><strong style="font-size: 12pt;">INET socket层：</strong>BSD socket是个可以用于各种网络协议的接口，而当用于tcp/ip，即建立了AF_INET形式的socket时，</div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">还需要保留些额外的参数，于是就有了struct sock结构。文件主要</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">有：/net/ipv4/protocol.c /net/ipv4/af_inet.c /net/core/sock.c etc</span><br /><br /><strong style="font-size: 12pt;">TCP/UDP层：</strong>处理传输层的操作，传输层用struct inet_protocol和struct proto两个结构表示。文件主要</div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">有：/net/ipv4/udp.c /net/ipv4/datagram.c /net/ipv4/tcp.c  /net/ipv4/tcp_input.c /net/ipv4//tcp_output.c /net/ipv4/tcp_minisocks.c  /net/ipv4/tcp_output.c&nbsp;/net/ipv4/tcp_timer.c </span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">etc&nbsp;&nbsp;</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><strong style="font-size: 12pt;">IP层：</strong>处理网络层的操作，网络层用struct packet_type结构表示。文件主要有：/net/ipv4/ip_forward.c </div> <div><span style="font-size: 12pt;">ip_fragment.c ip_input.c ip_output.c etc.</span><br /><br /><strong style="font-size: 12pt;">数据链路层和驱动程序：</strong>每个网络设备以struct net_device表示，通用的处理在dev.c中，驱动程序都在/driver/net目</div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">录下。</span></div> <div>&nbsp;</div> <div><strong style="font-size: 12pt;">2.</strong><span style="font-size: 12pt;"> </span><strong style="font-size: 12pt;">两台主机建立udp通信所走过的函数列表</strong></div> <div><strong></strong>&nbsp;</div> <div><span style="font-size: 12pt;">^</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sys_read&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs/read_write.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock_read&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/socket.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock_recvmsg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/socket.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inet_recvmsg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/af_inet.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;udp_recvmsg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/udp.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;skb_recv_datagram&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/core/datagram.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-------------------------------------------</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock_queue_rcv_skb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include/net/sock.h</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;udp_queue_rcv_skb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/udp.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;udp_rcv&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/udp.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip_local_deliver_finish net/ipv4/ip_input.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip_local_deliver&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/ip_input.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip_recv&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/ip_input.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net_rx_action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/dev.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-------------------------------------------</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;netif_rx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/dev.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el3_rx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driver/net/3c309.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el3_interrupt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driver/net/3c309.c</span><br /><br /><span style="font-size: 12pt;">＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</span><br /><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sys_write&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs/read_write.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock_writev&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/socket.c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock_sendmsg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/socket.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inet_sendmsg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/af_inet.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;udp_sendmsg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/udp.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip_build_xmit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/ip_output.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output_maybe_reroute&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/ip_output.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip_output&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/ip_output.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip_finish_output&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/ipv4/ip_output.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dev_queue_xmit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net/dev.c</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--------------------------------------------</span><br /><span style="font-size: 12pt;">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;el3_start_xmit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;driver/net/3c309.c</span><br /><span style="font-size: 12pt;">V</span></div> <div>&nbsp;</div> <div>&nbsp;</div> <div><strong style="font-size: 12pt;">3.</strong> <strong>网络路径图、重要数据结构sk_buffer及路由介绍</strong></div> <div><strong></strong>&nbsp;</div> <div><strong>&nbsp;&nbsp;&nbsp;&nbsp;</strong><span style="font-size: 12pt;">linux-net.pdf 第2.1章 第2.3章 第2.4章</span></div> <div>&nbsp;&nbsp;&nbsp;&nbsp;</div> <div><strong style="font-size: 12pt;">4.</strong> <strong>从连接、发送、到接收数据包的过程</strong></div> <div><strong></strong>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;linux-net.pdf 第4、5、6章详细阐述</span></div> <div>&nbsp;</div> <div>&nbsp;</div> <div><strong style="font-size: 14pt;">二.linux的tcp-ip栈代码的详细分析<br /><br /></strong></div> <div><strong></strong>&nbsp;</div> <div><strong style="font-size: 12pt;">1.数据结构(msghdr,sk_buff,socket,sock,proto_ops,proto)</strong></div> <div><strong></strong>&nbsp;</div> <div><span style="font-size: 12pt;">bsd套接字层,操作的对象是socket,数据存放在msghdr这样的数据结构：</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">创建socket需要传递family,type,protocol三个参数，创建socket其实就是创建一个socket实例，然后创建一 个文件描述符结构，并且互相建立一些关联，即建立互相连接的指针，并且初始化这些对文件的写读操作映射到socket的read，write函数上来。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">同时初始化socket的操作函数（proto_ops结构),如果传入的type参数是STREAM类型，那么就初始化为 SOCKET-&gt;ops为inet_stream_ops，如果是DGRAM类型，则SOCKET-ops为inet_dgram_ops。对于 inet_stream_ops其实是一个结构体，包含了stream类型的socket操作的一些入口函数，在这些函数里主要做的是对socket进行 相关的操作，同时通过调用下面提到的sock中的相关操作完成socket到sock层的传递。比如在inet_stream_ops里有个 inet_release的操作，这个操作除了释放socket的类型空间操作外，还通过调用socket连接的sock的close操作，对于 stream类型来说，即tcp_close来关闭sock</span></div> <div><span style="font-size: 12pt;">释放sock。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">创建socket同时还创建sock数据空间，初始化sock,初始化过程主要做的事情是初始化三个队列，receive_queue（接收到 的数据包sk_buff链表队列),send_queue(需要发送数据包的sk_buff链表队列),backlog_queue(主要用于tcp中三 次握手成功的那些数据包,自己猜的),根据family、type参数，初始化sock的操作，比如对于family为inet类型的，type为 stream类型的，sock-&gt;proto初始化为tcp_prot.其中包括stream类型的协议sock操作对应的入口函数。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">在一端对socket进行write的过程中，首先会把要write的字符串缓冲区整理成msghdr的数据结构形式(参见linux内核 2.4版源代码分析大全),然后调用sock_sendmsg把msghdr的数据传送至inet层，对于msghdr结构中数据区中的每个数据包，创建 sk_buff结构，填充数据，挂至发送队列。一层层往下层协议传递。一下每层协议不再对数据进行拷贝。而是对sk_buff结构进行操作。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">inet套接字及以下层 数据存放在sk_buff这样的数据结构里：</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">路由：</span></div> <div>&nbsp;&nbsp;&nbsp;&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;在linux的路由系统主要保存了三种与路由相关的数据，第一种是在物理上和本机相连接的主机地址信息表，第二种是保存了在网络访问中判断一个网络地址应该走什么路由的数据表；第三种是最新使用过的查询路由地址的缓存地址数据表。</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;1.neighbour结构 &nbsp;neighbour_table{  }是一个包含和本机所连接的所有邻元素的信息的数据结构。该结构中有个元素是neighbour结构的数组，数组的每一个元素都是一个对应于邻机的 neighbour结构，系统中由于协议的不同，会有不同的判断邻居的方式，每种都有neighbour_table{}类型的实例，这些实例是通过 neighbour_table{}中的指针next串联起来的。在neighbour结构中，包含有与该邻居相连的网络接口设备net_device的 指针，网络接口的硬件地址，邻居的硬件地址，包含有neigh_ops{}指针，这些函数指针是直接用来连接传输数据的，包含有 queue_xmit(struct * sk_buff)函数入口地址，这个函数可能会调用硬件驱动程序的发送函数。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; 2.FIB结构  在FIB中保存的是最重要的路由规则,通过对FIB数据的查找和换算，一定能够获得路由一个地址的方法。系统中路由一般采取的手段是：先到路由缓存中查找 表项，如果能够找到，直接对应的一项作为路由的规则；如果不能找到，那么就到FIB中根据规则换算传算出来，并且增加一项新的，在路由缓存中将项目添加进 去。</span></div>  <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; 3.route结构（即路由缓存中的结构)</span></div> <div>&nbsp;</div> <div>&nbsp;</div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">数据链路层：</span></div> <div>&nbsp;&nbsp; </div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;  net_device{}结构，对应于每一个网络接口设备。这个结构中包含很多可以直接获取网卡信息的函数和变量，同时包含很多对于网卡操作的函数，这些 直接指向该网卡驱动程序的许多函数入口，包括发送接收数据帧到缓冲区等。当这些完成后，比如数据接收到缓冲区后便由netif_rx(在net/core /dev.c各种设备驱动程序的上层框架程序)把它们组成sk_buff形式挂到系统接收的backlog队列然后交由上层网络协议处理。同样，对于上层 协议处理下来的那些sk_buff。便由dev_queue_xmit函数放入网络缓冲区，交给网卡驱动程序的发送程序处理。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;  在系统中存在一张链表dev_base将系统中所有的net_device{}结构连在一起。对应于内核初始化而言，系统启动时便为每个所有可能支持的网 络接口设备申请了一个net_device{}空间并串连起来，然后对每个接点运行检测过程，如果检测成功，则在dev_base链表中保留这个接点，否 则删除。对应于模块加载来说，则是调用register_netdev()注册net_device,在这个函数中运行检测过程，如果成功，则加到 dev_base链表。否则就返回检测不到信息。删除同理，调用</span></div> <div><span style="font-size: 12pt;">unregister_netdev。</span></div> <div>&nbsp;</div> <div>&nbsp;</div> <div><strong style="font-size: 12pt;">2.启动分析</strong></div> <div><strong></strong>&nbsp;</div> <div><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;2.1 初始化进程</strong> ：start-kernel(main.c)----&gt;do_basic_setup(main.c)----&gt;sock_init(/net/socket.c)----&gt;do_initcalls(main.c)</div> <div>&nbsp;</div> <div><strong style="font-size: 12pt;">void __init sock_init(void)<br /></strong>{<br />&nbsp;int i;</div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;printk(KERN_INFO "Linux NET4.0 for Linux 2.4\n");</span><br /><span style="font-size: 12pt;">&nbsp;printk(KERN_INFO "Based upon Swansea University Computer Society NET3.039\n");</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Initialize all address (protocol) families.  每一项表示的是针对一个地址族的操作集合，例如对于ipv4来说，在net/ipv4/af_inet.c文件中的函数 inet_proto_init()就调用sock_register()函数将inet_families_ops初始化到属于IPV4的 net_families数组中的一项。</span><br /><span style="font-size: 12pt;">&nbsp; */</span><br />&nbsp; <br /><span style="font-size: 12pt;">&nbsp;for (i = 0; i &lt; NPROTO; i++) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;net_families[i] = NULL;&nbsp;&nbsp;</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Initialize sock SLAB cache.初始化对于sock结构预留的内存的slab缓存。</span><br /><span style="font-size: 12pt;">&nbsp; */</span><br />&nbsp; <br /><span style="font-size: 12pt;">&nbsp;sk_init();</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">#ifdef SLAB_SKB</span><br /><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Initialize skbuff SLAB cache 初始化对于skbuff结构的slab缓存。以后对于skbuff的申请可以通过函数kmem_cache_alloc()在这个缓存中申请空间。</span><br /><span style="font-size: 12pt;">&nbsp; */</span><br /><span style="font-size: 12pt;">&nbsp;skb_init();</span><br /><span style="font-size: 12pt;">#endif</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Wan router layer. </span><br /><span style="font-size: 12pt;">&nbsp; */</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">#ifdef CONFIG_WAN_ROUTER&nbsp; </span><br /><span style="font-size: 12pt;">&nbsp;wanrouter_init();</span><br /><span style="font-size: 12pt;">#endif</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Initialize the protocols module.&nbsp;向系统登记sock文件系统，并且将其安装到系统上来。</span><br /><span style="font-size: 12pt;">&nbsp; */</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;register_filesystem(&amp;sock_fs_type);</span><br /><span style="font-size: 12pt;">&nbsp;sock_mnt = kern_mount(&amp;sock_fs_type);</span><br /><span style="font-size: 12pt;">&nbsp;/* The real protocol initialization is performed when</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp; do_initcalls is run.&nbsp; </span><br /><span style="font-size: 12pt;">&nbsp; */</span></div> <div><br /><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; * The netlink device handler may be needed early.</span><br /><span style="font-size: 12pt;">&nbsp; */</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">#ifdef CONFIG_NET</span><br /><span style="font-size: 12pt;">&nbsp;rtnetlink_init();</span><br /><span style="font-size: 12pt;">#endif</span><br /><span style="font-size: 12pt;">#ifdef CONFIG_NETLINK_DEV</span><br /><span style="font-size: 12pt;">&nbsp;init_netlink();</span><br /><span style="font-size: 12pt;">#endif</span><br /><span style="font-size: 12pt;">#ifdef CONFIG_NETFILTER</span><br /><span style="font-size: 12pt;">&nbsp;netfilter_init();</span><br /><span style="font-size: 12pt;">#endif</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">#ifdef CONFIG_BLUEZ</span><br /><span style="font-size: 12pt;">&nbsp;bluez_init();</span><br /><span style="font-size: 12pt;">#endif</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">/*yfhuang ipsec*/</span><br /><span style="font-size: 12pt;">#ifdef CONFIG_IPSEC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br /><span style="font-size: 12pt;">&nbsp;pfkey_init();</span><br /><span style="font-size: 12pt;">#endif</span><br /><span style="font-size: 12pt;">/*yfhuang ipsec*/</span><br /><span style="font-size: 12pt;">}</span></div> <div><strong></strong>&nbsp;</div> <div><strong></strong>&nbsp;</div> <div><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;2.2 do_initcalls()</strong>&nbsp;中做了其它的初始化，其中包括</div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;协议初始化，路由初始化，网络接口设备初始化</span></div> <div>&nbsp;</div> <div><strong style="font-size: 12pt;">(例如inet_init函数以_init开头表示是系统初始化时做，函数结束后跟 module_init(inet_init),这是一个宏，在include/linux/init.c中定义，展开为 _initcall(inet_init),表示这个函数在do_initcalls被调用了)</strong></div> <div>&nbsp;</div> <div><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;2.3 协议初始化</strong></div> <div><strong style="font-size: 12pt;">此处主要列举inet协议的初始化过程。</strong></div> <div><strong></strong>&nbsp;</div> <div><span style="font-size: 12pt;">static int __init inet_init(void)</span><br /><span style="font-size: 12pt;">{</span><br /><span style="font-size: 12pt;">&nbsp;struct sk_buff *dummy_skb;</span><br /><span style="font-size: 12pt;">&nbsp;struct inet_protocol *p;</span><br /><span style="font-size: 12pt;">&nbsp;struct inet_protosw *q;</span><br /><span style="font-size: 12pt;">&nbsp;struct list_head *r;</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;printk(KERN_INFO "NET4: Linux TCP/IP 1.0 for NET4.0\n");</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;if (sizeof(struct inet_skb_parm) &gt; sizeof(dummy_skb-&gt;cb)) {</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;printk(KERN_CRIT "inet_proto_init: panic\n");</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;return -EINVAL;</span><br /><span style="font-size: 12pt;">&nbsp;}</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Tell SOCKET that we are alive...&nbsp;注册socket，告诉socket inet类型的地址族已经准备好了</span><br /><span style="font-size: 12pt;">&nbsp; */</span><br />&nbsp;&nbsp; <br /><span style="font-size: 12pt;">&nbsp; &nbsp;(void) sock_register(&amp;inet_family_ops);</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Add all the protocols. 包括arp,ip、ICMP、UPD、tcp_v4、tcp、igmp的初始化，主要初始化各种协议对应的inode和socket变量。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">其中arp_init完成系统中路由部分neighbour表的初始化</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">ip_init完成ip协议的初始化。在这两个函数中，都通过定义一个packet_type结构的变量将这种数据包对应的协议发送数据、允许发送设备都做初始化。</span></div> <div><br /><span style="font-size: 12pt;">&nbsp; */</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;printk(KERN_INFO "IP Protocols: ");</span><br /><span style="font-size: 12pt;">&nbsp;for (p = inet_protocol_base; p != NULL;) {</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;struct inet_protocol *tmp = (struct inet_protocol *) p-&gt;next;</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;inet_add_protocol(p);</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;printk("%s%s",p-&gt;name,tmp?", ":"\n");</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;p = tmp;</span><br /><span style="font-size: 12pt;">&nbsp;}</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/* Register the socket-side information for inet_create. */</span><br /><span style="font-size: 12pt;">&nbsp;for(r = &amp;inetsw[0]; r &lt; &amp;inetsw[SOCK_MAX]; ++r)</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;INIT_LIST_HEAD(r);</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;for(q = inetsw_array; q &lt; &amp;inetsw_array[INETSW_ARRAY_LEN]; ++q)</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;inet_register_protosw(q);</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Set the ARP module up&nbsp; </span><br /><span style="font-size: 12pt;">&nbsp; */</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;arp_init();</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp; &nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; &nbsp; *&nbsp;Set the IP module up</span><br /><span style="font-size: 12pt;">&nbsp; &nbsp; */</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;ip_init();</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;tcp_v4_init(&amp;inet_family_ops);</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/* Setup TCP slab cache for open requests. */</span><br /><span style="font-size: 12pt;">&nbsp;tcp_init();</span></div> <div><br /><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Set the ICMP layer up</span><br /><span style="font-size: 12pt;">&nbsp; */</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;icmp_init(&amp;inet_family_ops);</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/* I wish inet_add_protocol had no constructor hook...</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; I had to move IPIP from net/ipv4/protocol.c :-( --ANK</span><br /><span style="font-size: 12pt;">&nbsp; */</span><br /><span style="font-size: 12pt;">#ifdef CONFIG_NET_IPIP</span><br /><span style="font-size: 12pt;">&nbsp;ipip_init();</span><br /><span style="font-size: 12pt;">#endif</span><br /><span style="font-size: 12pt;">#ifdef CONFIG_NET_IPGRE</span><br /><span style="font-size: 12pt;">&nbsp;ipgre_init();</span><br /><span style="font-size: 12pt;">#endif</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Initialise the multicast router</span><br /><span style="font-size: 12pt;">&nbsp; */</span><br /><span style="font-size: 12pt;">#if defined(CONFIG_IP_MROUTE)</span><br /><span style="font-size: 12pt;">&nbsp;ip_mr_init();</span><br /><span style="font-size: 12pt;">#endif</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;/*</span><br /><span style="font-size: 12pt;">&nbsp; *&nbsp;Create all the /proc entries.</span><br /><span style="font-size: 12pt;">&nbsp; */</span><br /><span style="font-size: 12pt;">#ifdef CONFIG_PROC_FS</span><br /><span style="font-size: 12pt;">&nbsp;proc_net_create ("raw", 0, raw_get_info);</span><br /><span style="font-size: 12pt;">&nbsp;proc_net_create ("netstat", 0, netstat_get_info);</span><br /><span style="font-size: 12pt;">&nbsp;proc_net_create ("snmp", 0, snmp_get_info);</span><br /><span style="font-size: 12pt;">&nbsp;proc_net_create ("sockstat", 0, afinet_get_info);</span><br /><span style="font-size: 12pt;">&nbsp;proc_net_create ("tcp", 0, tcp_get_info);</span><br /><span style="font-size: 12pt;">&nbsp;proc_net_create ("udp", 0, udp_get_info);</span><br /><span style="font-size: 12pt;">#endif&nbsp;&nbsp;/* CONFIG_PROC_FS */</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;ipfrag_init();</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;return 0;</span><br /><span style="font-size: 12pt;">}&nbsp;&nbsp;&nbsp;</span></div> <div><span style="font-size: 12pt;">module_init(inet_init);</span></div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div> <div>&nbsp;</div> <div>&nbsp;&nbsp;&nbsp;&nbsp;<strong style="font-size: 12pt;"> 2.4 路由初始化(包括neighbour表、FIB表、和路由缓存表的初始化工作)</strong></div> <div><strong></strong>&nbsp;</div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong style="font-size: 12pt;">2.4.1 rtcache表 ip_rt_init()函数 在net/ipv4/ip_output中调用，net/ipv4/route.c中定义</strong></div> <div><strong></strong>&nbsp;</div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong style="font-size: 12pt;">2.4.2 FIB初始化 在ip_rt_init()中调用 在net/ipv4/fib_front.c中定义</strong></div> <div><strong></strong>&nbsp;</div> <div><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.4.3 neigbour表初始化&nbsp;&nbsp;arp_init（）函数中定义&nbsp;</strong></div> <div><strong></strong>&nbsp;</div> <div><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.5 网络接口设备初始化</strong></div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在系统中网络接口都是由一个dev_base链表进行管理的。通过内核的启动方式也是通过这个链表进行操作的。在系 统启动之初，将所有内核能够支持的网络接口都初始化成这个链表中的一个节点，并且每个节点都需要初始化出init函数指针，用来检测网络接口设备。然后， 系统遍历整个dev_base链表，对每个节点分别调用init函数指针，如果成功，证明网络接口设备可用，那么这个节点就可以进一步初始化，如果返回失 败，那么证明该网络设备不存在或是不可用，只能将该节点删除。启动结束之后，在dev_base中剩下的都是可以用的网络接口设备。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.5.1  do_initcalls----&gt;net_dev_init()(net/core /dev.c)------&gt;ethif_probe()(drivers/net/Space.c,在netdevice{}结构的init中调 用，这边ethif_probe是以太网卡针对的调用)</span></div> <div>&nbsp;</div> <div><strong></strong>&nbsp;</div> <div><strong></strong>&nbsp;</div> <div><strong style="font-size: 12pt;">3.网络设备驱动程序（略)</strong></div> <div><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></div> <div><strong></strong>&nbsp;</div> <div><strong style="font-size: 12pt;">4.网络连接</strong></div> <div><strong></strong>&nbsp;</div> <div><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.1 连接的建立和关闭</strong></div> <div><strong></strong>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tcp连接建立的代码如下:</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server=gethostbyname(SERVER_NAME);</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sockfd=socket(AF_INET,SOCK_STREAM,0);</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;address.sin_family=AF_INET；</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;address.sin_port=htons(PORT_NUM);</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memcpy(&amp;address.sin_addr,server-&gt;h_addr,server-&gt;h_length);</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connect(sockfd,&amp;address,sizeof(address));</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;连接的初始化与建立期间主要发生的事情如下：</span></div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1）sys_socket调用：调用socket_creat(),创建出一个满足传入参数family、type、和 protocol的socket,调用sock_map_fd()获取一个未被使用的文件描述符，并且申请并初始化对应的file{}结构。</span></div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2）sock_creat()：创建socket结构，针对每种不同的family的socket结构的初始化，就需要调用不同 的create函数来完成。对应于inet类型的地址来说，在网络协议初始化时调用sock_register()函数中完成注册的定义如下：</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct net_proto_family inet_family_ops={</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PF_INET;</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inet_create</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};所以inet协议最后会调用inet_create函数。</span></div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3）inet_create:  初始化sock的状态设置为SS_UNCONNECTED,申请一个新的sock结构，并且初始化socket的成员ops初始化为 inet_stream_ops,而sock的成员prot初始化为tcp_prot。然后调用sock_init_data,将该socket结构的变 量sock和sock类型的变量关联起来。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4）在系统初始化完毕后便是进行connect的工作，系统调用connect将一个和socket结构关联的文件描述符和一个 sockaddr{}结构的地址对应的远程机器相关联，并且调用各个协议自己对应的connect连接函数。对应于tcp类型，则 sock-&gt;ops-&gt;connect便为inet_stream_connect。</span></div> <div>&nbsp;</div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5）inet_stream_connect:  得到sk,sk=sock-&gt;sk,锁定sk，对自动获取sk的端口号存放在sk-&gt;num中，并且用htons()函数转换存放在sk-&amp; gt;sport中。然后调用sk-&gt;prot-&gt;connect()函数指针，对tcp协议来说就是tcp_v4_connect()函 数。然后将sock-&gt;state状态字设置为SS_CONNECTING,等待后面一系列的处理完成之后，就将状态改成 SS_CONNECTTED。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6)  tcp_v4_connect()：调用函数ip_route_connect()，寻找合适的路由存放在rt中。ip_route_connect找两 次，第一次找到下一跳的ip地址，在路由缓存或fib中找到，然后第二次找到下一跳的具体邻居，到neigh_table中找到。然后申请出tcp头的空 间存放在buff中。将sk中相关地址数据做一些针对路由的变动，并且初始化一个tcp连接的序列号，调用函数tcp_connect（），初始化tcp 头，并设置tcp处理需要的定时器。一次connect（）建立的过程就结束了。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;连接的关闭主要如下：</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1）close: 一个socket文件描述符对应的file{}结构中，有一个file_operations{}结构的成员f_ops，它的初始化关闭函数为sock_close函数。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2）sock_close：调用函数sock_release(),参数为一个socket{}结构的指针。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3）sock_release：调用inet_release，并释放socket的指针和文件空间</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4）inet_release: 调用和该socket对应协议的关闭函数inet_release,如果是tcp协议，那么调用的是tcp_close；最后释放sk。</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.2 </span><strong style="font-size: 12pt;">数据发送流程图</strong></div> <div><strong></strong>&nbsp;</div> <div>&nbsp;<img alt="" src="http://blog.csdn.net/images/blog_csdn_net/cz_hyf/send.gif" usemap="#mymap" border="0" /></div> <div><strong></strong>&nbsp;</div> <div><span style="font-size: 12pt;">各层主要函数以及位置功能说明：</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1)sock_write：初始化msghdr{}结构 net/socket.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2)sock_sendmsg:net/socket.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3)inet_sendmsg:net/ipv4/af_net.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4)tcp_sendmsg：申请sk_buff{}结构的空间，把msghdr{}结构中的数据填入sk_buff空间。net/ipv4/tcp.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5)tcp_send_skb:net/ipv4/tcp_output.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6)tcp_transmit_skb:net/ipv4/tcp_output.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7)ip_queue_xmit:net/ipv4/ip_output.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8)ip_queue_xmit2:net/ipv4/ip_output.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9)ip_output:net/ipv4/ip_output.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10)ip_finish_output:net/ipv4/ip_output.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;11)ip_finish_output2:net/ipv4/ip_output.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;12)neigh_resolve_output:net/core/neighbour.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;13)dev_queue_xmit:net/core/dev.c</span></div> <div>&nbsp;</div> <div>&nbsp;</div> <div><strong style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.3 数据接收流程图</strong></div> <div><img alt="" src="http://blog.csdn.net/images/blog_csdn_net/cz_hyf/receive.gif" usemap="#mymap" border="0" /></div> <div><strong></strong>&nbsp;</div> <div><span style="font-size: 12pt;">各层主要函数以及位置功能说明：</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1)sock_read:初始化msghdr{}的结构类型变量msg，并且将需要接收的数据存</span><span style="font-size: 12pt;">放的地址传给msg.msg_iov-&gt;iov_base.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; net/socket.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2)sock_recvmsg: 调用函数指针sock-&gt;ops-&gt;recvmsg()完成在INET  Socket层的数据接收过程.其中sock-&gt;ops被初始化为inet_stream_ops,其成员recvmsg对应的函数实现为 inet_recvmsg()函数. net/socket.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3)sys_recv()/sys_recvfrom():分别对应着面向连接和面向无连接的协议两种情况. net/socket.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4)inet_recvmsg:调用sk-&gt;prot-&gt;recvmsg函数完成数据接收,这个函数对于tcp协议便是tcp_recvmsg net/ipv4/af_net.c</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5)tcp_recvmsg:从网络协议栈接收数据的动作,自上而下的触发动作一直到这个函数为止,出现了一次等待的过程.函 数tcp_recvmsg可能会被动地等待在sk的接收数据队列上,也就是说,系统中肯定有其他地方会去修改这个队列使得tcp_recvmsg可以进行 下去.入口参数sk是这个网络连接对应的sock{}指针,msg用于存放接收到的数据.接收数据的时候会去遍历接收队列中的数据,找到序列号合适的.</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;但读取队列为空时tcp_recvmsg就会调用tcp_v4_do_rcv使用backlog队列填充接收队列.</span></div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6)tcp_v4_rcv:tcp_v4_rcv被ip_local_deliver函数调用,是从IP层协议向INET  Socket层提交的"数据到"请求,入口参数skb存放接收到的数据,len是接收的数据的长度,这个函数首先移动skb-&gt;data指针,让它 指向tcp头,然后更新tcp层的一些数据统计,然后进行tcp的一些值的校验.再从INET  Socket层中已经建立的sock{}结构变量中查找正在等待当前到达数据的哪一项.可能这个sock{}结构已经建立,或者还处于监听端口、等待数据 连接的状态。返回的sock结构指针存放在sk中。然后根据其他进程对sk的操作情况,将skb发送到合适的位置.调用如下:</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TCP包接收器(tcp_v4_rcv)将TCP包投递到目的套接字进行接收处理.  当套接字正被用户锁定,TCP包将暂时排入该套接字的后备队列(sk_add_backlog).这时如果某一用户线程企图锁定该套接字 (lock_sock),该线程被排入套接字的后备处理等待队列(sk-&gt;lock.wq).当用户释放上锁的套接字时 (release_sock,在tcp_recvmsg中调用),后备队列中的TCP包被立即注入TCP包处理器(tcp_v4_do_rcv)进行处 理,然后唤醒等待队列中最先的一个用户来获得其锁定权. 如果套接字未被上锁,当用户正在读取该套接字时,  TCP包将被排入套接字的预备队列(tcp_prequeue),将其传递到该用户线程上下文中进行处理.如果添加到sk-&gt;prequeue不成 功,便可以添加到 sk-&gt;receive_queue队列中(用户线程可以登记到预备队列,当预备队列中出现第一个包时就唤醒等待线程.)&nbsp;&nbsp;  /net/tcp_ipv4.c</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;7)ip_rcv、ip_rcv_finish:从以太网接收数据，放到skb里，作ip层的一些数据及选项检查，调用 ip_route_input()做路由处理,判断是进行ip转发还是将数据传递到高一层的协议.调用skb-&gt;dst-&gt;input函数指 针,这个指针的实现可能有多种情况,如果路由得到的结果说明这个数据包应该转发到其他主机,这里的input便是ip_forward;如果数据包是给本 机的,那么input指针初始化为ip_local_deliver函数./net/ipv4/ip_input.c</span></div> <div>&nbsp;</div> <div><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8)ip_local_deliver、ip_local_deliver_finish:入口参数skb存放需要传送到上层 协议的数据,从ip头中获取是否已经分拆的信息,如果已经分拆,则调用函数ip_defrag将数据包重组。然后通过调用 ip_prot-&gt;handler指针调用tcp_v4_rcv(tcp)。ip_prot是inet_protocol结构指针,是用来ip层登 记协议的，比如由udp,tcp,icmp等协议。 /net/ipv4/ip_input.c</span></div></div></div><img src ="http://www.cppblog.com/finehai/aggbug/172589.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-24 13:50 <a href="http://www.cppblog.com/finehai/archive/2012/04/24/172589.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】C++ 虚函数表解析 </title><link>http://www.cppblog.com/finehai/archive/2012/04/24/172574.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 24 Apr 2012 03:44:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/24/172574.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172574.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/24/172574.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172574.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172574.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C++中的虚函数的作用主要是实现了多态的机制。关于多态，简而言之就是用父类型别的指针指向其子类的实例，然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”，这是一种泛型技术。所谓泛型技术，说白了就是试图使用不变的代码来实现可变的算法。比如：模板技术，RTTI技术，虚函数技术，要么是试图做到在编译时决议，要么试图做到运行时决议。&nbsp;&nbsp;<a href='http://www.cppblog.com/finehai/archive/2012/04/24/172574.html'>阅读全文</a><img src ="http://www.cppblog.com/finehai/aggbug/172574.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-24 11:44 <a href="http://www.cppblog.com/finehai/archive/2012/04/24/172574.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gnu binutils(addr2line ar gprof nm objcopy ...)</title><link>http://www.cppblog.com/finehai/archive/2012/04/24/172557.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 24 Apr 2012 02:28:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/24/172557.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172557.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/24/172557.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172557.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172557.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: GNU binutils是一组二进制工具集。包括：addr2line ar gprof nm objcopy objdump ranlib size strings strip. 本文归纳他们的常用法。&nbsp;&nbsp;<a href='http://www.cppblog.com/finehai/archive/2012/04/24/172557.html'>阅读全文</a><img src ="http://www.cppblog.com/finehai/aggbug/172557.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-24 10:28 <a href="http://www.cppblog.com/finehai/archive/2012/04/24/172557.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android中Message机制的灵活应用</title><link>http://www.cppblog.com/finehai/archive/2012/04/23/172481.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Mon, 23 Apr 2012 10:23:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/23/172481.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172481.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/23/172481.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172481.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172481.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1.活用Android线程间通信的Message机制  1.1.Message 代码在frameworks\base\core\java\android\Os\Message.java中。  Message.obtain函数：有多个obtain函数，主要功能一样，只是参数不一样。作用是从Message  Pool中取出一个Message，如果Message  Pool中已经没有Message可取则...&nbsp;&nbsp;<a href='http://www.cppblog.com/finehai/archive/2012/04/23/172481.html'>阅读全文</a><img src ="http://www.cppblog.com/finehai/aggbug/172481.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-23 18:23 <a href="http://www.cppblog.com/finehai/archive/2012/04/23/172481.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebKit之布局(layout)</title><link>http://www.cppblog.com/finehai/archive/2012/04/23/172479.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Mon, 23 Apr 2012 09:35:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/23/172479.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172479.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/23/172479.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172479.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172479.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt;"> </span><div><span style="font-size: 12pt;">WebKit 在渲染页面之前，需要确定各个元素的位置、大小，而这个过程就是layout(布局)。下面，我们对layout的主要过程进行一番说明。 </span><br /> <br /><span style="font-size: 12pt;">一、FrameView::layout方法 </span><br /><br /><span style="font-size: 12pt;">FrameView作为与View相关的类，其主要涉及与显示相关的内容，而其中对页面元素的布局至关重要，这也是浏览器的核心处理部分。 </span><br /> <br /><span style="font-size: 12pt;">我们都知道浏览器从Web服务器获得数据后，经解析会构建DOM树、Render树，然后进行布局处理，进而为渲染页面作好准备，其中的布局处理往往由FrameView::layout方法发起，让我们来具体看看其实现，一窥其主要实现过程。 </span><br /> <br /><span style="font-size: 12pt;">void FrameView::layout(bool allowSubtree) </span><br /><span style="font-size: 12pt;">{ </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (m_midLayout) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return; </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // Always ensure our style info is up-to-date. This can happen  in situations where the layout beats any sort of style recalc update  that needs to occur. </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // 进行CSSStyleSelector的更新处理，因为一旦CSS发生变化，布局的结果也可能 发生相关变化，所以在开始布局之前，需要检查CSS是否发生变化，如果有则需要作相应调整，进而可能影响Render树等。 </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (m_frame-&gt;needsReapplyStyles()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_frame-&gt;reapplyStyles(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; else if (document-&gt;childNeedsStyleRecalc()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document-&gt;recalcStyle(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; bool subtree = m_layoutRoot; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; RenderObject* root = subtree ? m_layoutRoot : document-&gt;renderer(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (!root) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // FIXME: Do we need to set m_size here? </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_layoutSchedulingEnabled = true; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; } </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; //布局的处理可能相互嵌套，这与发起布局处理的时机相关。 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; //设置滚动条相关 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (m_canHaveScrollbars) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hMode = ScrollbarAuto; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vMode = ScrollbarAuto; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; } else { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hMode = ScrollbarAlwaysOff; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vMode = ScrollbarAlwaysOff; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; } </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (!subtree) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Now set our scrollbar state for the layout. </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (body-&gt;hasTagName(framesetTag) &amp;&amp; !m_frame-&gt;settings()-&gt;frameFlatteningEnabled()) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // frameset 而且设置了frameFlatteningEnabled，则关闭滚动条 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; body-&gt;renderer()-&gt;setChildNeedsLayout(true); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vMode = ScrollbarAlwaysOff; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hMode = ScrollbarAlwaysOff; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (body-&gt;hasTagName(bodyTag)) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 设置滚动条 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; applyOverflowToViewport(o, hMode, vMode); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; } </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; //root往往为RenderView对象 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; RenderLayer* layer = root-&gt;enclosingLayer(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; m_midLayout = true; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; beginDeferredRepaints(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; root-&gt;layout(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; endDeferredRepaints(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; m_midLayout = false; </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; m_layoutSchedulingEnabled = true; </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (!subtree &amp;&amp; !static_cast(root)-&gt;printing()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adjustViewSize(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // Now update the positions of all layers. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; //对当前Render树布局完后，设置RenderLayer树的布局信息，其中m_doFullRepaint描述是否需要发起渲染处理。 </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp; beginDeferredRepaints(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp; layer-&gt;updateLayerPositions(...); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp; endDeferredRepaints(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // 设置快速blit </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; setCanBlitOnScroll(!useSlowRepaints()); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; //因为在布局的过程中，可能进一步获得网页数据，则需要继续布局处理。 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (!m_postLayoutTasksTimer.isActive()) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Calls resumeScheduledEvents() </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; performPostLayoutTasks(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!m_postLayoutTasksTimer.isActive() &amp;&amp; needsLayout()) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Post-layout widget updates or an event handler made  us need layout again. Lay out again, but this time defer widget updates  and event dispatch until after we return. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_postLayoutTasksTimer.startOneShot(0); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pauseScheduledEvents(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layout(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; } else { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resumeScheduledEvents(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; } </span><br /><span style="font-size: 12pt;">} </span><br />  <br /> <br /><span style="font-size: 12pt;">FrameView::layout方法，简单的说来就是发起对Render树中的每一个节点按照从父节点到子节点的方式进行x、y、width、height计算，当每一个树节点的位置及大小确定之后就可以进行后面的渲染。 </span><br /> <br /><span style="font-size: 12pt;">FrameView::layout往往会调用Render树根的layout方法即RenderView::layout。 </span><br /><br /> <br /><span style="font-size: 12pt;">二、RenderView::layout方法 </span><br /> <br /><span style="font-size: 12pt;">void RenderView::layout() </span><br /><span style="font-size: 12pt;">{ </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; if (printing()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_minPrefWidth = m_maxPrefWidth = m_width; </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; bool relayoutChildren = !printing() &amp;&amp; (!m_frameView || m_width != viewWidth() || m_height != viewHeight()); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; if (relayoutChildren) { </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setChildNeedsLayout(true, false); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (RenderObject* child = firstChild(); child; child = child-&gt;nextSibling()) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (child-&gt;style()-&gt;height().isPercent() ||  child-&gt;style()-&gt;minHeight().isPercent() ||  child-&gt;style()-&gt;maxHeight().isPercent()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child-&gt;setChildNeedsLayout(true, false); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><br /> <br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; } </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; ASSERT(!m_layoutState); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; LayoutState state; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // FIXME: May be better to push a clip and avoid issuing offscreen repaints. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; state.m_clipped = false; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; m_layoutState = &amp;state; </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; if (needsLayout()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RenderBlock::layout();//类继承的好处，直接调用父类的layout </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // Reset overflow and then replace it with docWidth and docHeight. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; m_overflow.clear(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; addLayoutOverflow(IntRect(0, 0, docWidth(), docHeight())); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; ASSERT(m_layoutStateDisableCount == 0); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; ASSERT(m_layoutState == &amp;state); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; m_layoutState = 0; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; setNeedsLayout(false); </span><br /><span style="font-size: 12pt;">} </span><br /> <br /><span style="font-size: 12pt;">void RenderBlock::layout() </span><br /><span style="font-size: 12pt;">{ </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // Update our first letter info now. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; updateFirstLetter(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // Table cells call layoutBlock directly, so don't add any logic here. Put code into layoutBlock(). </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; layoutBlock(false); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // It's safe to check for control clip here, since controls can  never be table cells. If we have a lightweight clip, there can never be  any overflow from children. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (hasControlClip() &amp;&amp; m_overflow) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clearLayoutOverflow(); </span><br /><span style="font-size: 12pt;">} </span><br />  <br /> <br /> <br /><span style="font-size: 12pt;">三、RenderBlock::layoutBlock方法 </span><br /> <br /><span style="font-size: 12pt;">layoutBlock 会分成两个分支：layoutInlineChildren 和 layoutBlockChildren </span><br /> <br /><span style="font-size: 12pt;">void RenderBlock::layoutBlock(bool relayoutChildren) </span><br /><span style="font-size: 12pt;">{ </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; ... </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; calcWidth();//先计算宽度 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; calcColumnWidth(); </span><br />&nbsp;&nbsp;&nbsp;  <br /> <br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; m_overflow.clear();&nbsp;&nbsp;&nbsp;  </span><br /> <br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (oldWidth != width() || oldColumnWidth != desiredColumnWidth()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; relayoutChildren = true; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; clearFloats(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; int previousHeight = height(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; setHeight(0); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; //这就是在布局基本概念中提到的Block-level元素的子节点要么是Block-level元素要么为Inline-level元素。 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; if (childrenInline()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layoutInlineChildren(relayoutChildren, repaintTop, repaintBottom); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; else </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layoutBlockChildren(relayoutChildren, maxFloatBottom); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // Expand our intrinsic height to encompass floats. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; if (floatBottom() &gt; (m_height - toAdd) &amp;&amp;  (isInlineBlockOrInlineTable() || isFloatingOrPositioned() ||  hasOverflowClip() || </span><br /><span style="font-size: 12pt;">(parent() &amp;&amp; parent()-&gt;isFlexibleBox() || m_hasColumns))) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; setHeight(floatBottom() + toAdd); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // Now lay out our columns within this intrinsic height, since  they can slightly affect the intrinsic height as we adjust for clean  column breaks. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; int singleColumnBottom = layoutColumns(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // Calculate our new height.//布局完子节点后确定父节点高度 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; int oldHeight = height(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; calcHeight(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; if (previousHeight != height()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; relayoutChildren = true; </span><br /> <br /> <br /> <br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; //另外布局属性为Fixed和absolute的元素 </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; layoutPositionedObjects(relayoutChildren || isRoot()); </span><br /> <br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if we overflow or not. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; updateScrollInfoAfterLayout(); </span><br /> <br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // Repaint with our new bounds if they are different from our old bounds. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; bool didFullRepaint = repainter.repaintAfterLayout(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; if (!didFullRepaint &amp;&amp; repaintTop != repaintBottom  &amp;&amp; (style()-&gt;visibility() == VISIBLE ||  enclosingLayer()-&gt;hasVisibleContent())) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 设置repaintRect </span><br /> <br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Make sure the rect is still non-empty after intersecting for overflow above </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!repaintRect.isEmpty()) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repaintRectangle(repaintRect); // We need to do a partial repaint of our content. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (hasReflection()) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; repaintRectangle(reflectedRect(repaintRect)); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; } </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; setNeedsLayout(false); </span><br /><span style="font-size: 12pt;">} </span><br /> <br />  <br /><span style="font-size: 12pt;">四、RenderBlock::layoutBlockChildren方法 </span><br /> <br /> <br /><span style="font-size: 12pt;">void RenderBlock::layoutBlockChildren(bool relayoutChildren, int&amp; maxFloatBottom) </span><br /><span style="font-size: 12pt;">{ </span><br /><span style="font-size: 12pt;">int top = borderTop() + paddingTop(); </span><br /><span style="font-size: 12pt;">int bottom = borderBottom() + paddingBottom() + horizontalScrollbarHeight(); </span><br /> <br /> <br /> <br /> <br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // Fieldsets need to find their legend and position it inside the border of the object. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // The legend then gets skipped during normal layout. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; RenderObject* legend = layoutLegend(relayoutChildren); </span><br /> <br /> <br /> <br /><span style="font-size: 12pt;">//遍历子节点 </span><br /> <br /><span style="font-size: 12pt;">RenderBox* next = firstChildBox(); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; while (next) { </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RenderBox* child = next; </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; next = child-&gt;nextSiblingBox(); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (legend == child) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue; // Skip the legend, since it has already been positioned up in the fieldset's border. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Make sure we layout children if they need it. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // an auto value.&nbsp; Add a method to determine this, so that we can avoid the relayout. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (relayoutChildren ||  ((child-&gt;style()-&gt;height().isPercent() ||  child-&gt;style()-&gt;minHeight().isPercent() ||  child-&gt;style()-&gt;maxHeight().isPercent()) &amp;&amp;  !isRenderView())) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child-&gt;setChildNeedsLayout(true, false); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (relayoutChildren &amp;&amp;  (child-&gt;style()-&gt;paddingLeft().isPercent() ||  child-&gt;style()-&gt;paddingRight().isPercent())) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child-&gt;setPrefWidthsDirty(true, false); </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Handle the four types of special elements first.&nbsp; These include positioned content, floating content, compacts and </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // run-ins.&nbsp; When we encounter these four types of objects, we don't actually lay them out as normal flow blocks. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (handleSpecialChild(child, marginInfo)) </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue; </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Lay out the child. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; layoutBlockChild(child, marginInfo, previousFloatBottom, maxFloatBottom); </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; } </span><br /> <br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // Now do the handling of the bottom of the block, adding in our bottom border/padding and </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; // determining the correct collapsed bottom margin information. </span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp; handleBottomOfBlock(top, bottom, marginInfo); </span><br /><span style="font-size: 12pt;">} </span><br /> <br /><span style="font-size: 12pt;">layoutBlockChild 方法就比较复杂了，具体可以自己看代码。 </span><br /><br /> <br /><span style="font-size: 12pt;">五、RenderBlock::layoutInlineChildren方法 </span><br /><br /><span style="font-size: 12pt;">这个方法相当复杂，其作用就是布局文字、图像等，对文字行高确定、断行等处理，同时还包括 文字从左到右或从右到左的布局处理。具体可以参考bidi.cpp中的源码实现。 </span><br /><br /> <br /><span style="font-size: 12pt;">六、调用FrameView::layout方法的时机 </span><br /><br /><span style="font-size: 12pt;">由于从Web服务器获取的网页数据不可能一次性完成，往往需要边获取数据，边布局，然后渲染，这样才可能获得良好的用户感受。 </span><br /> <br /><span style="font-size: 12pt;">所以一旦获得主要数据如css数据及body等标签后，就可以开始布局，布局完后会根据当前条件决定是否将布局的数据渲染出来，或者继续布局处理后来获取的数据，这样也增加了布局处理过程的复杂度。 </span><br /> <br /><span style="font-size: 12pt;">而调用layout方法的时机也至关重要，因为layout本身就可能需要花费大量的时间如layoutBlockChildren、 layoutInlineChildren等处理，其往往与网页的内容有关，而网页的内容却由网页开发者来确定，对浏览器来讲是千变万化的，这就对 layout方法的实现及调用时机提出更高的要求，同时确定了其复杂性。 </span><br /> <br /><span style="font-size: 12pt;">调用layout的时机主要有获得一定DOM文档数据后调用Document::updateLayout()、需要重新使用CSS数据时调用Document::recalcStyle()、改变窗口大小后调用Frame::forceLayout()等来实现。。。 </span><br /><br /> <br /><span style="font-size: 12pt;">七、总结 </span><br /><br /><span style="font-size: 12pt;">其实WebKit涉及网页布局方面的layout方法蛮复杂的，如其他RenderObject子类也会根据自身情况重载实现layout，还有对float、fixed、absolute、inline元素等的处理，但其主要逻辑就象上面所提，这里只是汇总一下主要流程及概念，针对每一个具体标签或RenderObject的布局实现则需要更深一步的了解，希望大家能对了解WebKit的网页布局过程有一个清晰而准确的认识。。  </span><br />  </div><img src ="http://www.cppblog.com/finehai/aggbug/172479.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-23 17:35 <a href="http://www.cppblog.com/finehai/archive/2012/04/23/172479.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android SDK、NDK、JNI的简单介绍</title><link>http://www.cppblog.com/finehai/archive/2012/04/23/172476.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Mon, 23 Apr 2012 09:25:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/23/172476.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172476.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/23/172476.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172476.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172476.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt;"> </span><span style="font-size: 14pt; color: red;"><strong>1、SDK</strong></span><div><span style="font-size: 12pt; color: red;"></span></div><span style="font-size: 12pt; color: red;"><strong><br /></strong></span><span style="font-size: 12pt;">（software development kit）软件开发工具包。被软件开发工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。因此！Android SDk 指的既是Android专属的软件开发工具包</span><span style="font-size: 12pt;"> <br /></span><br /><span style="font-size: 12pt;"><br /></span><span style="font-size: 14pt; color: #ff0000;"><strong>2、JNI</strong></span><br /><br /><span style="font-size: 12pt;">Java  Native Interface (JNI)标准是java平台的一部分，它允许Java代码和其他语言写的代码进行交互。JNI  是本地编程接口，它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++  和汇编语言)编写的应用程序和库进行交互操作</span><br /><span style="font-size: 12pt;">当然一般需要进行如下操作流程：</span><br /><span style="font-size: 12pt;">1) 编写java程序：这里以HelloWorld为例。为了实现在 java代码中调用c函数printf。</span><br /><span style="font-size: 12pt;">　　代码1：</span><br /><pre java;=""><span style="font-size: 12pt;">class HelloWorld {</span><br /><span style="font-size: 12pt;">　　public native void testHelloWorld();</span><br /><span style="font-size: 12pt;">　　static {</span><br /><span style="font-size: 12pt;">　　System.loadLibrary("hello");</span><br /><span style="font-size: 12pt;">　　}</span><br /><span style="font-size: 12pt;">　　public static void main(String[] args) {</span><br /><span style="font-size: 12pt;">　　new HelloWorld().testHelloWorld();</span><br /><span style="font-size: 12pt;">　　}</span><br /><span style="font-size: 12pt;">　　}</span></pre><br /><span style="font-size: 12pt;">声明native方法：如果你想将一个方法做为一个本地方法的话，那么你就必须声明改方法为native的，并且不能实现。</span><br /><span style="font-size: 12pt;">Load动态库：System.loadLibrary("hello");</span><br /><span style="font-size: 12pt;">这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary()的参数&#8220;hello&#8221;是动态库的名字。</span><br /><span style="font-size: 12pt;">2) 编译</span><br /><span style="font-size: 12pt;">javac HelloWorld.java</span><br /><span style="font-size: 12pt;">3) 生成扩展名为h的头文件 javah ?</span><br /><span style="font-size: 12pt;">JNIEXPORT void JNICALL Java_HelloWorld_testHelloWorld (JNIEnv *, jobject);</span><br /><span style="font-size: 12pt;">这 个h文件相当于我们在java里面的接口，这里声明了一个 Java_HelloWorld_testHelloWorld (JNIEnv *,  jobject)方法，然后在我们 的本地方法里面实现这个方法，也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致）。</span><br /><span style="font-size: 12pt;">4) 编写本地方法实现和由javah命令生成的头文件里面声明的方法名相同的方法</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代码2：</span><br /><pre java;=""><span style="font-size: 12pt;">#include "jni.h"</span><br /><span style="font-size: 12pt;">　　#include "HelloWorld.h"</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#include other headers</span><br /><span style="font-size: 12pt;">JNIEXPORT void JNICALL Java_HelloWorld_testHelloWorld(JNIEnv *env, jobject obj)</span><br /><span style="font-size: 12pt;">{</span><br /><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;printf("Hello world!\n");</span><br /><span style="font-size: 12pt;">　 return;</span><br /><span style="font-size: 12pt;">}</span></pre><br /><span style="font-size: 12pt;">注 意代码2中的第1行，需要将jni.h（该文件可以在%JAVA_HOME%/include文件夹下面找到）文件引入，因为在程序中的JNIEnv、  jobject等类型都是在该头文件中定义的；另外在第2行需要将HelloWorld.h头文件引入。然后保存为  HelloWorldImpl.c就ok了。</span><br /><span style="font-size: 12pt;">5) 生成动态库</span><br /><span style="font-size: 12pt;">　　这里以在Windows中为例，需要生成dll文件。在保存 HelloWorldImpl.c文件夹下面，使用VC的编译器cl成。 cl -I%java_home%\include  -I%java_home%\include\win32 -LD HelloWorldImp.c -Fehello.dll  注意：生成的dll文件名在选项-Fe后面配置，这里是hello，因为在HelloWorld.java文件中我们loadLibary的时候使用的名 字是hello。</span><br /><span style="font-size: 12pt;">另外需要将-I%java_home%\include -I%java_home%\include\win32参数加上，因为在第四步里面编写本地方法的时候引入了jni.h文件。</span><br /><br /><strong><span style="font-size: 14pt; color: #ff0000;">3、NDK</span></strong><br /><br /><span style="font-size: 12pt;">NDK全称：Native Development Kit。</span><br /><span style="font-size: 12pt;">NDK是一系列工具的集合。</span><br /><span style="font-size: 12pt;">* NDK提供了一系列的工具，帮助开发者快速开发C（或C++）的动态库，并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。</span><br /><span style="font-size: 12pt;">* NDK集成了交叉编译器，并提供了相应的mk文件隔离CPU、平台、ABI等差异，开发人员只需要简单修改mk文件（指出&#8220;哪些文件需要编译&#8221;、&#8220;编译特性要求&#8221;等），就可以创建出so。</span><br /><span style="font-size: 12pt;">* NDK可以自动地将so和Java应用一起打包，极大地减轻了开发人员的打包工作。</span><br /><span style="font-size: 12pt;">其实：</span><br /><span style="font-size: 12pt;">NDK就是能够方便快捷开发.so文件的工具。JNI的过程比较复杂，生成.so需要大量操作，而NDK就是简化了这个过程。</span><br /><span style="font-size: 12pt;">打个不恰当比方：JNI 需要自己买菜、洗菜、炒菜、煮饭，很麻烦；NDK就是宅急送，一个电话。</span><br /><br /><span style="font-size: 12pt;">本文转自</span><a href="http://dev.10086.cn/cmdn/bbs/thread-38855-1-11.html" target="_blank"><span style="font-size: 12pt;">http://dev.10086.cn/cmdn/bbs/thread-38855-1-11.html</span></a><img src ="http://www.cppblog.com/finehai/aggbug/172476.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-23 17:25 <a href="http://www.cppblog.com/finehai/archive/2012/04/23/172476.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于 Android NDK 的学习之旅-----环境搭建</title><link>http://www.cppblog.com/finehai/archive/2012/04/23/172469.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Mon, 23 Apr 2012 09:05:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/23/172469.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/172469.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/23/172469.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/172469.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/172469.html</trackback:ping><description><![CDATA[<br />
<p style="text-indent: 21pt;"><span style="font-family: 宋体; font-size: 12pt;">工欲善其事</span> <span style="font-family: 宋体; font-size: 12pt;">必先利其器</span><span style="font-size: 12pt;"> , </span><span style="font-family: 宋体; font-size: 12pt;">下面介绍下</span><span style="font-size: 12pt;"> Eclipse SDK NDK Cygwin CDT </span><span style="font-family: 宋体; font-size: 12pt;">集成开发环境的搭建。</span></p><p style="text-indent: 21pt;"><span style="font-family: 宋体; font-size: 12pt;"><br /></span></p>
<h3><span style="font-size: 14pt;">1、Android开发环境搭建</span><span style="font-family: 宋体; font-size: 14pt;"></span></h3>
<p style="text-indent: 18pt;"><span style="font-size: 12pt;">Android</span><span style="font-family: 宋体; font-size: 12pt;">开发环境搭建不是重点</span><span style="font-size: 12pt;">,</span><span style="font-family: 宋体; font-size: 12pt;">相信看此文章的很多人都已经搭建成功</span><span style="font-size: 12pt;">,</span><span style="font-family: 宋体; font-size: 12pt;">这里随便概述性的说说。</span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><span><span style="font-size: 12pt;">1)<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; font-size: 12pt;">下载</span><span style="font-size: 12pt;"> JDK</span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><span><span style="font-size: 12pt;">2)<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; font-size: 12pt;">下载</span><span style="font-size: 12pt;"> Eclipse</span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><span><span style="font-size: 12pt;">3)<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; font-size: 12pt;">下载</span><span style="font-size: 12pt;"> Android SDK</span></p>
<p style="margin-left: 60pt; text-indent: -18pt;"><span><span style="font-size: 12pt;">4)<span style="font: 7pt 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; font-size: 12pt;">启动</span><span style="font-size: 12pt;">Eclipse , </span><span style="font-family: 宋体; font-size: 12pt;">安装</span><span style="font-size: 12pt;"> ADT</span></p>
<p style="margin-left: 42pt;"><span face="宋体" style="font-family: 宋体;"><br />
</span></p>
<h3><span style="font-size: 14pt;">2、下载安装Android NDK</span><span style="font-size: 14pt;"></span></h3>
<p style="margin-left: 18pt;"><span style="font-family: 宋体; font-size: 12pt;">我使用的</span><span style="font-size: 12pt;">NDK</span><span style="font-family: 宋体; font-size: 12pt;">版本为</span><span style="font-size: 12pt;">r5</span></p>
<p style="margin-left: 18pt;"><span style="font-size: 12pt;">Google </span><span style="font-family: 宋体; font-size: 12pt;">出的最新</span><span style="font-size: 12pt;">NDK </span><span style="font-family: 宋体; font-size: 12pt;">为</span><span style="font-size: 12pt;"> r6 </span><span style="font-family: 宋体; font-size: 12pt;">下载地址为</span> </p>
<p style="margin-left: 18pt;"><a href="http://developer.android.com/sdk/ndk/index.html"><span style="font-size: 12pt;">http://developer.android.com/sdk/ndk/index.html</span></a></p>
<p style="margin-left: 18pt;">&nbsp;</p>
<h3><span style="font-size: 14pt;">3、下载安装cygwin</span><span style="font-size: 14pt;"></span></h3>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: Verdana; color: #403226;">&nbsp;&nbsp; &nbsp;</span>&nbsp;<span style="font-size: 12pt;">由于</span><span style="font-size: 12pt; font-family: 'Times New Roman';">NDK</span><span style="font-size: 12pt;">编译代码时必须要用到</span><span style="font-size: 12pt; font-family: 'Times New Roman';">make</span><span style="font-size: 12pt;">和</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gcc</span><span style="font-size: 12pt;">，所以你必须先搭建一个</span><span style="font-size: 12pt; font-family: 'Times New Roman';">linux</span><span style="font-size: 12pt;">环境，</span><span style="font-size: 12pt; font-family: 'Times New Roman';"> cygwin</span><span style="font-size: 12pt;">是一个在</span><span style="font-size: 12pt; font-family: 'Times New Roman';">windows</span><span style="font-size: 12pt;">平台上运行的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">unix</span><span style="font-size: 12pt;">模拟环境</span><span style="font-size: 12pt; font-family: 'Times New Roman';">,</span><span style="font-size: 12pt;">它对于学习</span><span style="font-size: 12pt; font-family: 'Times New Roman';">unix/linux</span><span style="font-size: 12pt;">操作环境，或者从</span><span style="font-size: 12pt; font-family: 'Times New Roman';">unix</span><span style="font-size: 12pt;">到</span><span style="font-size: 12pt; font-family: 'Times New Roman';">windows</span><span style="font-size: 12pt;">的应用程序移植，非常有用。通过它，你就可以在不安装</span><span style="font-size: 12pt; font-family: 'Times New Roman';">linux</span><span style="font-size: 12pt;">的情况下使用</span><span style="font-size: 12pt; font-family: 'Times New Roman';">NDK</span><span style="font-size: 12pt;">来编译</span><span style="font-size: 12pt; font-family: 'Times New Roman';">C</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">C++</span><span style="font-size: 12pt;">代码了。下面我们一步一步的安装</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">吧。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;">&nbsp;<span style="font-size: 12pt;">（安装的时候忘记截图了）</span></p>
<p style="margin: 0cm 0cm 0.0001pt; line-height: 18pt;"><span style="font-size: 12pt;">首先，你得先跑到</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';"><a href="http://www.cygwin.com/"><span style="font-size: 12pt; color: windowtext; text-decoration: none;">http://www.cygwin.com</span></a></span><span style="font-size: 12pt;">下载</span><span style="font-size: 12pt; font-family: 'Times New Roman';">setup.exe</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">1</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">然后双击运行吧，运行后你将看到安装向导界面：</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">2</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">点击下一步</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; </span><span style="font-size: 12pt;">此时让你选择安装方式：</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1</span><span style="font-size: 12pt;">）</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Install from Internet</span><span style="font-size: 12pt;">：直接从</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Internet</span><span style="font-size: 12pt;">上下载并立即安装（安装完成后，下载好的安装文件并不会被</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';"></span><span style="font-size: 12pt;">删除，而是仍然被保留，以便下次再安装）。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2</span><span style="font-size: 12pt;">）</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Download Without Installing</span><span style="font-size: 12pt;">：只是将安装文件下载到本地，但暂时不安装。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3</span><span style="font-size: 12pt;">）</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Install from Local Directory</span><span style="font-size: 12pt;">：不下载安装文件，直接从本地某个含有安装文件的目录进行安装。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">3</span><span style="font-size: 12pt;">、选择第一项，然后点击下一步：</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">4</span><span style="font-size: 12pt;">、选择要安装的目录，注意，最好不要放到有中文和空格的目录里，似乎会造成安装出问题，其它选项不用变，</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';"> </span><span style="font-size: 12pt;">之后点下一步：</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">5</span><span style="font-size: 12pt;">、上一步是选择安装</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">的目录，这个是选择你下载的安装包所在的目录，默认是你运行</span><span style="font-size: 12pt; font-family: 'Times New Roman';">setup.exe</span><span style="font-size: 12pt;">的目</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';"></span><span style="font-size: 12pt;">录，直接点下一步就可以：</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">6</span><span style="font-size: 12pt;">、此时你共有三种连接方式选择：</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; 1) Direct Connection</span><span style="font-size: 12pt;">：直接连接。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; 2) Use IE5 Settings</span><span style="font-size: 12pt;">：使用</span><span style="font-size: 12pt; font-family: 'Times New Roman';">IE</span><span style="font-size: 12pt;">的连接参数设置进行连接。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp; &nbsp; &nbsp;3) Use HTTP/FTP Proxy</span><span style="font-size: 12pt;">：使用</span><span style="font-size: 12pt; font-family: 'Times New Roman';">HTTP</span><span style="font-size: 12pt;">或</span><span style="font-size: 12pt; font-family: 'Times New Roman';">FTP</span><span style="font-size: 12pt;">代理服务器进行连接（需要输入服务器地址、端口号）。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="font-size: 12pt;">用户可根据自己的网络连接的实情情况进行选择，一般正常情况下，均选择第一种，也就是直接连接方式。然后</span><span style="font-size: 12pt;">再点击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&#8220;</span><span style="font-size: 12pt;">下一步</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&#8221;</span><span style="font-size: 12pt;">，</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">7</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">这是选择要下载的站点，我用的是</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';"><a href="http://mirrors.kernel.org/"><span style="font-size: 12pt; color: windowtext; text-decoration: none;">http://mirrors.kernel.org</span></a></span><span style="font-size: 12pt;">，速度感觉还挺快，选择后点下一步</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">8</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">此时会下载加载安装包列表</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">9</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Search</span><span style="font-size: 12pt;">是可以输入你要下载的包的名称，能够快速筛选出你要下载的包。那四个单选按钮是选择下边树的样式，默认就行，不用动。</span><span style="font-size: 12pt; font-family: 'Times New Roman';">View</span><span style="font-size: 12pt;">默认是</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Category</span><span style="font-size: 12pt;">，建议改成</span><span style="font-size: 12pt; font-family: 'Times New Roman';">full</span><span style="font-size: 12pt;">显示全部包再查，省的一些包被隐藏掉。左下角那个复选框是是否隐藏过期包，默认打钩，不用管它就行，下边开始下载我们要安装的包吧，为了避免全部下载，这里列出了后面开发</span><span style="font-size: 12pt; font-family: 'Times New Roman';">NDK</span><span style="font-size: 12pt;">用得着的包：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">autoconf2.1</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">automake1.10</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">binutils</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gcc-core</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gcc- g++</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gcc4-core</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gcc4-g++</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gdb</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">pcre</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">pcre-devel</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gawk</span><span style="font-size: 12pt;">、</span><span style="font-size: 12pt; font-family: 'Times New Roman';">make</span><span style="font-size: 12pt;">共</span><span style="font-size: 12pt; font-family: 'Times New Roman';">12</span><span style="font-size: 12pt;">个包</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">10</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">然后开始选择安装这些包吧，点</span><span style="font-size: 12pt; font-family: 'Times New Roman';">skip</span><span style="font-size: 12pt;">，把它变成数字版本格式，要确保</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Bin</span><span style="font-size: 12pt;">项变成叉号，而</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Src</span><span style="font-size: 12pt;">项是源码，这个就没必要选了。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">11</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">下面测试一下</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">是不是已经安装好了。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="font-size: 12pt;">运行</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">，在弹出的命令行窗口输入：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygcheck -c cygwin</span><span style="font-size: 12pt;">命令，会打印出当前</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">的版本和运行状</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';"> &nbsp; &nbsp; &nbsp; </span><span style="font-size: 12pt;">态，如果</span><span style="font-size: 12pt; font-family: 'Times New Roman';">status</span><span style="font-size: 12pt;">是</span><span style="font-size: 12pt; font-family: 'Times New Roman';">ok</span><span style="font-size: 12pt;">的话，则</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">运行正常。</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="font-size: 12pt;">然后依次输入</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gcc &#8211;version</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt; font-family: 'Times New Roman';">g++ --version</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt; font-family: 'Times New Roman';">make &#8211;version</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt; font-family: 'Times New Roman';">gdb &#8211;version</span><span style="font-size: 12pt;">进行测试，如果都打印出版本信息和一些描述信息，非常高兴的告诉你，你的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">安装完成了！</span></p><p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt;"><br /></span></p>
<h3><span style="font-size: 14pt;">4、配置NDK环境变量</span><span style="font-family: 宋体; font-size: 14pt;"></span></h3>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">1</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">首先找到</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">的安装目录，找到一个</span><span style="font-size: 12pt; font-family: 'Times New Roman';">home\&lt;</span><span style="font-size: 12pt;">你的用户名</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&gt;\.bash_profile</span><span style="font-size: 12pt;">文件，我的是：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">E:\cygwin\home\Administrator\.bash_profile</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt; font-family: 'Times New Roman';">(</span><span style="font-size: 12pt;">注意：我安装的时候我的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">home</span><span style="font-size: 12pt;">文件夹下面神马都没有，解决</span> <span style="font-size: 12pt;">的办法：首先打开环境变量，把里面的用户变量中的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">HOME</span><span style="font-size: 12pt;">变量删掉，在</span><span style="font-size: 12pt; font-family: 'Times New Roman';">E:\cygwin\home</span><span style="font-size: 12pt;">文件夹下建立名为</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Administrator</span><span style="font-size: 12pt;">的文件夹（是用户名），然后把</span><span style="font-size: 12pt; font-family: 'Times New Roman';">E:\cygwin\etc\skel\.bash_profile</span><span style="font-size: 12pt;">拷贝到该文件夹下</span><span style="font-size: 12pt; font-family: 'Times New Roman';">)</span><span style="font-size: 12pt;">。</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">2</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">打开</span><span style="font-size: 12pt; font-family: 'Times New Roman';">bash_profile</span><span style="font-size: 12pt;">文件，添加</span><span style="font-size: 12pt; font-family: 'Times New Roman';">NDK=/cygdrive/&lt;</span><span style="font-size: 12pt;">你的盘符</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&gt;/&lt;android ndk </span><span style="font-size: 12pt;">目录</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&gt; </span><span style="font-size: 12pt;">例如：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">NDK=/cygdrive/e/android-ndk-r5</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">export NDK</span></p>
<p style="margin: 3.75pt 0cm; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">NDK</span><span style="font-size: 12pt;">这个名字是随便取的，为了方面以后使用方便，选个简短的名字，然后保存</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">3</span><span style="font-size: 12pt;">、打开</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">，输入</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cd $NDK</span><span style="font-size: 12pt;">，如果输出上面配置的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">/cygdrive/e/android-ndk-r5</span><span style="font-size: 12pt;">信息，则表明环境变量设置成功了。</span></p><p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt;"><br /></span></p>
<h3><span style="font-size: 14pt;">5、用NDK来编译程序</span></h3>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">1</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">现在我们用安装好的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">NDK</span><span style="font-size: 12pt;">来编译一个简单的程序吧，我们选择</span><span style="font-size: 12pt; font-family: 'Times New Roman';">ndk</span><span style="font-size: 12pt;">自带的例子</span><span style="font-size: 12pt; font-family: 'Times New Roman';">hello-jni</span><span style="font-size: 12pt;">，我的位于</span><span style="font-size: 12pt; font-family: 'Times New Roman';">E:\android-ndk-r5\samples\hello-jni(</span><span style="font-size: 12pt;">根据你具体的安装位置而定</span><span style="font-size: 12pt; font-family: 'Times New Roman';">)</span><span style="font-size: 12pt;">，</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">2</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">运行</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">，输入命令</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cd /cygdrive/e/android-ndk-r5/samples/hello-jni</span><span style="font-size: 12pt;">，进入到</span><span style="font-size: 12pt; font-family: 'Times New Roman';">E:\android-ndk-r5\samples\hello-jni</span><span style="font-size: 12pt;">目录。</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">3</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">输入</span><span style="font-size: 12pt; font-family: 'Times New Roman';">$NDK/ndk-build</span><span style="font-size: 12pt;">，执行成功后，它会自动生成一个</span><span style="font-size: 12pt; font-family: 'Times New Roman';">libs</span><span style="font-size: 12pt;">目录，把编译生成的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">.so</span><span style="font-size: 12pt;">文件放在里面。</span><span style="font-size: 12pt; font-family: 'Times New Roman';">($NDK</span><span style="font-size: 12pt;">是调用我们之前配置好的环境变量，</span><span style="font-size: 12pt; font-family: 'Times New Roman';">ndk-build</span><span style="font-size: 12pt;">是调用</span><span style="font-size: 12pt; font-family: 'Times New Roman';">ndk</span><span style="font-size: 12pt;">的编译程序</span><span style="font-size: 12pt; font-family: 'Times New Roman';">)</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">4</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">此时去</span><span style="font-size: 12pt; font-family: 'Times New Roman';">hello-jni</span><span style="font-size: 12pt;">的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">libs</span><span style="font-size: 12pt;">目录下看有没有生成的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">.so</span><span style="font-size: 12pt;">文件，如果有，你的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">ndk</span><span style="font-size: 12pt;">就运行正常啦！</span></p><p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt;"><br /></span></p>
<h3><span style="font-size: 14pt;">6、在Eclipse中集成C/C++开发环境</span></h3>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: Verdana; color: #403226;">&nbsp; </span><span style="font-size: 12pt; font-family: 'Times New Roman';">1</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">装</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Eclipse</span><span style="font-size: 12pt;">的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">C/C++</span><span style="font-size: 12pt;">环境插件：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">CDT</span><span style="font-size: 12pt;">，这里选择在线安装。</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: 'Times New Roman';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-size: 12pt;">首先登录</span><span style="font-size: 12pt; font-family: 'Times New Roman';">http://www.eclipse.org/cdt/downloads.php</span><span style="font-size: 12pt;">，找到对应你</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Eclipse</span><span style="font-size: 12pt;">版本的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">CDT</span><span style="font-size: 12pt;">插件的在线安装地址。</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp;2</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">然后点</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Help</span><span style="font-size: 12pt;">菜单，找到</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Install New Software</span><span style="font-size: 12pt;">菜单</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp;3</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">点击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Add</span><span style="font-size: 12pt;">按钮，把取的地址填进去，出来插件列表后，选</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Select All</span><span style="font-size: 12pt;">，然后选择下一步即可完成安装</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp;4</span><span style="font-size: 12pt;">、</span><span style="font-size: 10.5pt; font-family: 'Times New Roman';">&nbsp;&nbsp;</span><span style="font-size: 12pt;">安装完成后，在</span><span style="font-size: 12pt; font-family: 'Times New Roman';">eclispe</span><span style="font-size: 12pt;">中右击新建一个项目，如果出现了</span><span style="font-size: 12pt; font-family: 'Times New Roman';">c/c++</span><span style="font-size: 12pt;">项目，则表明你的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">CDT</span><span style="font-size: 12pt;">插件安装成功啦！</span></p><p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><br style="font-size: 14pt;" /><span style="font-size: 12pt;"></span></p>
<h3><span style="font-size: 14pt;">7、配置C/C++的编译器</span><span style="font-family: 宋体; font-size: 14pt;"></span></h3>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp;1</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">打开</span><span style="font-size: 12pt; font-family: 'Times New Roman';">eclipse</span><span style="font-size: 12pt;">，导入</span><span style="font-size: 12pt; font-family: 'Times New Roman';">ndk</span><span style="font-size: 12pt;">自带的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">hello-jni</span><span style="font-size: 12pt;">例子，右键单击项目名称，点击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Properties</span><span style="font-size: 12pt;">，弹出配置界面，之后再点击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Builders</span><span style="font-size: 12pt;">，弹出项目的编译工具列表，之后点击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">New</span><span style="font-size: 12pt;">，新添加一个编译器，点击后出现添加界面，选择</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Program</span><span style="font-size: 12pt;">，点</span>&nbsp;<span style="font-size: 12pt;">击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">OK</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp; 2</span><span style="font-size: 12pt;">、出现了添加界面，首先给编译配置起个名字，如：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">C_Builder</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: 'Times New Roman';">&nbsp;&nbsp;</span><span style="font-size: 12pt;">设置</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Location</span><span style="font-size: 12pt;">为</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&lt;</span><span style="font-size: 12pt;">你</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">安装路径</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&gt;\bin\bash.exe</span><span style="font-size: 12pt;">程序，例如：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">E:\cygwin\bin\bash.exe</span><span style="font-size: 12pt;">，设置</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Working Directory</span><span style="font-size: 12pt;">为</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&lt;</span><span style="font-size: 12pt;">你</span><span style="font-size: 12pt; font-family: 'Times New Roman';">cygwin</span><span style="font-size: 12pt;">安装路径</span><span style="font-size: 12pt; font-family: 'Times New Roman';">&gt;\bin</span><span style="font-size: 12pt;">目录，例如：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">E:\cygwin\bin</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 10.5pt; font-family: 'Times New Roman';">&nbsp;&nbsp;</span><span style="font-size: 12pt;">设置</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Arguments</span><span style="font-size: 12pt;">为</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;&nbsp;--login -c "cd /cygdrive/I/JavaWorkSpace/Blog/NDK_02 &amp;&amp; $NDK/ndk-build"</span></p>
<p><img src="http://pic002.cnblogs.com/images/2011/154043/2011081310412218.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;">&nbsp;<span style="font-size: 12pt;">上面的配置中</span><span style="font-size: 12pt; font-family: 'Times New Roman';"> /cygdrive/I/JavaWorkSpace/Blog/NDK_02</span><span style="font-size: 12pt;">是你当前要编译的程序的目录，</span><span style="font-size: 12pt; font-family: 'Times New Roman';">$NDK</span><span style="font-size: 12pt;">是之前配置</span>&nbsp;<span style="font-size: 12pt;">的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">ndk</span><span style="font-size: 12pt;">的环境变量，这两个根据你具体的安装目录进行配置，其他的不用变，</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Arguments</span><span style="font-size: 12pt;">这串参数实际是</span>&nbsp;<span style="font-size: 12pt;">给</span><span style="font-size: 12pt; font-family: 'Times New Roman';">bash.exe</span><span style="font-size: 12pt;">命令行程序传参数，进入要编译的程序目录，然后运行</span><span style="font-size: 12pt; font-family: 'Times New Roman';">ndk-build</span><span style="font-size: 12pt;">编译程序</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">3</span><span style="font-size: 12pt;">、接着切换到</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Refresh</span><span style="font-size: 12pt;">选项卡，给</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Refresh resources upon completion</span><span style="font-size: 12pt;">打上钩</span></p>
<p><img src="http://pic002.cnblogs.com/images/2011/154043/2011081310413278.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">4</span><span style="font-size: 12pt;">、然后切换到</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Build Options</span><span style="font-size: 12pt;">选项卡，勾选上最后三项</span></p>
<p><img src="http://pic002.cnblogs.com/images/2011/154043/2011081310414128.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">5</span><span style="font-size: 12pt;">、之后点击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Specify Resources</span><span style="font-size: 12pt;">按钮，选择资源目录，勾选你的项目目录即可</span></p>
<p><img src="http://pic002.cnblogs.com/images/2011/154043/2011081310415084.png" alt="" style="display: block; margin-left: auto; margin-right: auto;" /></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;6</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">最后点击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Finish</span><span style="font-size: 12pt;">，点击</span><span style="font-size: 12pt; font-family: 'Times New Roman';">OK</span><span style="font-size: 12pt;">一路把刚才的配置都保存下来，注意：如果你配置的编译器在其它编译器下边，记得一定要点</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Up</span><span style="font-size: 12pt;">按钮，把它排到第一位，否则</span><span style="font-size: 12pt; font-family: 'Times New Roman';">C</span><span style="font-size: 12pt;">代码的编译晚于</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Java</span><span style="font-size: 12pt;">代码的编译，会造成你的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">C</span><span style="font-size: 12pt;">代码要编译两次才能看到最新的修改</span></p>
<p style="margin: 3.75pt 0cm; text-indent: 21pt; line-height: 18pt;"><span style="font-size: 12pt; font-family: 'Times New Roman';">&nbsp;7</span><span style="font-size: 12pt;">、</span>&nbsp;<span style="font-size: 12pt;">这一路下来肯定很累了吧，现在再次恭喜你，编译配置也配置完成啦，现在来测试一下是否可以自动编译呢，打开项目</span><span style="font-size: 12pt; font-family: 'Times New Roman';">jni</span><span style="font-size: 12pt;">目录里的</span><span style="font-size: 12pt; font-family: 'Times New Roman';">hello-jni.c</span><span style="font-size: 12pt;">文件把提示</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Hello from JNI!</span><span style="font-size: 12pt;">改成其他的文字：如：</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Hello</span><span style="font-size: 12pt;">，</span><span style="font-size: 12pt; font-family: 'Times New Roman';">My name is alex.</span><span style="font-size: 12pt;">，然后再模拟器中运行你的程序，如果模拟器中显示了你最新修改的文字，那么</span><span style="font-size: 12pt; font-family: 'Times New Roman';">Congratulations</span><span style="font-size: 12pt;">！你已经全部配置成功啦！</span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体; font-size: 12pt;">　　文章参考</span> <a href="http://yueguc.iteye.com/blog/946724"><span style="color: windowtext; text-decoration: none; font-size: 12pt;">http://yueguc.iteye.com/blog/946724</span></a></p>
<p><a href="http://yueguc.iteye.com/blog/946724"><span style="color: windowtext; text-decoration: none;"><br />
</span></a></p>
<p><span style="font-size: 12pt;">本文转自</span><a href="http://www.cnblogs.com/luxiaofeng54/archive/2011/08/13/2136982.html"><span style="font-size: 12pt;">http://www.cnblogs.com/luxiaofeng54/archive/2011/08/13/2136982.html</span></a><br />
<a href="http://yueguc.iteye.com/blog/946724"><span style="color: windowtext; text-decoration: none;"></span></a></p><img src ="http://www.cppblog.com/finehai/aggbug/172469.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-23 17:05 <a href="http://www.cppblog.com/finehai/archive/2012/04/23/172469.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ubuntu中 JDK的安装和卸载</title><link>http://www.cppblog.com/finehai/archive/2012/04/17/171759.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 17 Apr 2012 08:01:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/17/171759.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/171759.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/17/171759.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/171759.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/171759.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt;"> </span><div><p><strong style="font-size: 12pt;">1）安装Java JDK</strong></p><p><strong style="font-size: 12pt;">系统：Ubuntu 10.04</strong></p><p><strong style="font-size: 12pt;">JDK：jdk-6u21-linux-i586.bin</strong></p><p><strong style="font-size: 12pt;">下载好必要的jdk，</strong></p><p><strong style="font-size: 12pt;">一.安装JDK</strong></p><p><strong style="font-size: 12pt;">1.安装JDK</strong></p><div><p><strong style="font-size: 12pt;">1. sudo&nbsp;chmod&nbsp;u+x&nbsp;jdk-6u16-linux-i586.bin</strong></p><p><strong style="font-size: 12pt;">2. sudo&nbsp;cp&nbsp;-a&nbsp;jdk-6u21-linux-i586.bin&nbsp;/opt</strong></p><p><strong style="font-size: 12pt;">3. sudo&nbsp;/opt/jdk-6u21-linux-i586.bin</strong></p><p><strong style="font-size: 12pt;">4. sudo&nbsp;rm&nbsp;-f&nbsp;/opt/jdk-6u21-linux-i586.bin</strong></p></div><p><strong style="font-size: 12pt;">2.设置JDK环境变量</strong></p><div><p><strong style="font-size: 12pt;">sudo&nbsp;gedit&nbsp;/etc/profile</strong></p><p><strong style="font-size: 12pt;">添加代码:</strong></p><p><strong style="font-size: 12pt;">#set&nbsp;java&nbsp;environment</strong></p><p><strong style="font-size: 12pt;">export&nbsp;JAVA_HOME=/opt/jdk1.6.0_21</strong></p><p><strong style="font-size: 12pt;">export&nbsp;JRE_HOME=$JAVA_HOME/jreexport</strong></p><p><strong style="font-size: 12pt;">CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib</strong></p><p><strong style="font-size: 12pt;">export&nbsp;PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin</strong></p><p><strong style="font-size: 12pt;">保存退出。</strong></p><p><strong><br /></strong></p></div><p><strong style="font-size: 12pt;">3.重启系统</strong></p><p><strong><br /></strong></p><p><strong style="font-size: 12pt;">4.测试是否安装成功</strong></p><div><p><strong style="font-size: 12pt;">java&nbsp;-version</strong></p><p><strong style="font-size: 12pt;">如果显示</strong></p><p><strong style="font-size: 12pt;">java version &#8220;1.6.0_21&#8243;</strong></p><p><strong style="font-size: 12pt;">Java(TM) SE Runtime Environment (build 1.6.0_21-b06)</strong></p><p><strong style="font-size: 12pt;">Java HotSpot(TM) Server VM (build 17.0-b16, mixed mode)</strong></p><p><strong style="font-size: 12pt;">则安装成功。</strong></p><p><strong><br /></strong></p></div><p><strong style="font-size: 12pt;">二.卸载JDK</strong></p><p><strong><br /></strong></p><p><strong style="font-size: 12pt;">1.删除JDK目录</strong></p><div><strong style="font-size: 12pt;">sudo&nbsp;rm&nbsp;-rf&nbsp;/opt/jdk1.6.0_21</strong></div><p><strong style="font-size: 12pt;">2.删除JDK环境变量</strong></p><div><p><strong style="font-size: 12pt;">sudo&nbsp;gedit&nbsp;/etc/profile</strong></p><p><strong style="font-size: 12pt;">删除代码:</strong></p><p><strong style="font-size: 12pt;">#set java environment</strong></p><p><strong style="font-size: 12pt;">export JAVA_HOME=/opt/jdk1.6.0_21</strong></p><p><strong style="font-size: 12pt;">export JRE_HOME=$JAVA_HOME/jre</strong></p><p><strong style="font-size: 12pt;">export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib</strong></p><p><strong style="font-size: 12pt;">export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin保</strong></p><p><strong style="font-size: 12pt;">存退出。</strong></p></div></div><img src ="http://www.cppblog.com/finehai/aggbug/171759.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-17 16:01 <a href="http://www.cppblog.com/finehai/archive/2012/04/17/171759.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android之webkit内核JNI层与Java层 函数互相调用方法 </title><link>http://www.cppblog.com/finehai/archive/2012/04/17/171757.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 17 Apr 2012 07:58:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/17/171757.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/171757.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/17/171757.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/171757.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/171757.html</trackback:ping><description><![CDATA[<div><h1><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">Java<span style="font-family: 宋体;">层调用</span><span style="font-family: Arial;">JNI</span><span style="font-family: 宋体;">层函数：</span></span></h1> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">例子</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">：</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">Java<span style="font-family: 宋体;">层</span><span style="font-family: Times New Roman;">:&nbsp;BrowserFrame::loadurl(&nbsp;)&nbsp;</span></span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;<span style="font-family: 宋体;">调用</span><span style="font-family: Times New Roman;">JNI</span><span style="font-family: 宋体;">别名</span><span style="font-family: Times New Roman;">:&nbsp;Nativeloadurl()&nbsp;;</span></span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">JNI&nbsp;<span style="font-family: 宋体;">层：</span></span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">WebFrame::loadurl(&nbsp;)</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">&nbsp;;</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;"></span><span style="font-family: 'Times New Roman'; font-size: 12pt; color: red;">&nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt; color: red;"><div>  <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; color: #ff0000; font-size: 12pt; font-weight: normal;">1、将<span style="font-family: Times New Roman;">java</span><span style="font-family: 宋体;">层中的函数对应</span><span style="font-family: Times New Roman;">JNI</span><span style="font-family: 宋体;">层中的函数，以方便调用之。</span></span></p></div></span><span style="font-family: 'Times New Roman'; font-size: 12pt; color: #000000;"><br /></span></p><p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt; color: #000000;">在JNI层定义需要用的函数</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold; color: #000000;">WebFrame::</span><span style="font-family: '宋体'; background: none repeat scroll 0% 0% #ffff00; font-size: 12pt; font-weight: bold; color: #000000;">loadurl</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold; color: #000000;">(&nbsp;)</span></p><p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold; color: red;"><br /></span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp; &nbsp; &nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt;"> static&nbsp;void&nbsp;</span><span style="font-family: 'Times New Roman'; background: none repeat scroll 0% 0% #ffff00; font-size: 12pt;">LoadUrl</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">(JNIEnv&nbsp;*env,&nbsp;jobject&nbsp;obj,&nbsp;jstring&nbsp;url)</span></p><br /> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">-----------------------------------------------------------------------------------------</span></p> <p style="margin-top: 0pt; text-indent: 0.84pt; margin-bottom: 0pt; margin-left: -0.945pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">&nbsp;&nbsp;</span><span style="font-family: '宋体'; color: #0000ff; font-size: 12pt; font-weight: bold;">jniRegisterNativeMethods</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">(JNIEnv*&nbsp;env,&nbsp;const&nbsp;char*&nbsp;</span><span style="font-family: '宋体'; color: #0000ff; font-size: 12pt; font-weight: bold;">className</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">,</span></p> <p style="margin-top: 0pt; text-indent: 24pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">const&nbsp;</span><span style="font-family: '宋体'; color: #0000ff; font-size: 12pt; font-weight: bold;">JNINativeMethod</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">*&nbsp;</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">gMethods</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">,&nbsp;int&nbsp;</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">numMethods</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">)</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">//&nbsp;</span><span style="font-family: '宋体'; color: #0000ff; font-size: 12pt; font-weight: normal;">className&nbsp;</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">：<span style="font-family: Times New Roman;">java</span><span style="font-family: 宋体;">层的</span></span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">类名</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">。</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">//&nbsp;gMethods&nbsp;<span style="font-family: 宋体;">：对应</span></span><span style="font-family: '宋体'; color: #0000ff; font-size: 12pt; font-weight: bold;">JNINativeMethod</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">的数组。</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">------------------------------------------------------------------------------------------</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">typedef&nbsp;struct&nbsp;{&nbsp;</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;char*&nbsp;name;&nbsp;//<span style="font-family: 宋体;">函数名</span><span style="font-family: Times New Roman;">(java</span><span style="font-family: 宋体;">层中声明</span><span style="font-family: Times New Roman;">)</span></span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;char*&nbsp;signature;&nbsp;//&nbsp;<span style="font-family: 宋体;">函数参数</span></span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void*&nbsp;fnPtr;&nbsp;//&nbsp;<span style="font-family: 宋体;">函数指针（指向</span><span style="font-family: Times New Roman;">JNI</span><span style="font-family: 宋体;">层&nbsp;</span><span style="font-family: Times New Roman;">-&gt;&nbsp;WebFrame::loadurl(&nbsp;)&nbsp;)</span></span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">}&nbsp;</span><span style="font-family: '宋体'; color: #0000ff; font-size: 12pt; font-weight: bold;">JNINativeMethod</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">;</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">------------------------------------------------------------------------------------------</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">Eg.&nbsp;&nbsp;</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">将如上<span style="font-family: Times New Roman;">JNI</span><span style="font-family: 宋体;">函数使用别名：</span></span><span style="font-family: '宋体'; color: #ff9900; font-size: 12pt; font-weight: bold;">Nativeloadurl</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">(&nbsp;)</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">&nbsp;(java<span style="font-family: 宋体;">层中声明</span><span style="font-family: Times New Roman;">)</span><span style="font-family: 宋体;">，存于注册数组中。</span></span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; color: #0000ff; font-size: 12pt; font-weight: bold;">JNINativeMethod&nbsp;</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: bold;">gMethods[]={</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">{&nbsp;"</span><span style="font-family: '宋体'; color: #ff9900; font-size: 12pt; font-weight: bold;">nativeLoadUrl</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">",&nbsp;"(Ljava/lang/String;)V",&nbsp;(void*)&nbsp;</span><span style="font-family: '宋体'; background: none repeat scroll 0% 0% #ffff00; font-size: 12pt; font-weight: bold;">LoadUrl&nbsp;</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">}</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">...</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">}</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">------------------------------------------------------------------------------------------</span></p><p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;"><br /></span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal; color: #ff0000;">2.&nbsp;</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal; color: #ff0000;">在<span style="font-family: Times New Roman; color: #ff0000;">Java</span><span style="font-family: 宋体; color: #ff0000;">层中声明并调用函数：</span><span style="font-family: Times New Roman; color: #ff0000;">nativeLoadUrl(String&nbsp;url)</span></span></p><p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal; color: #ff0000;"><span style="font-family: Times New Roman; color: #ff0000;"><br /></span></span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">&nbsp;&nbsp;&nbsp;&nbsp;声明：</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">private&nbsp;</span><span style="font-family: '宋体'; color: #ff0000; font-size: 12pt; font-weight: normal;">native&nbsp;</span><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">void&nbsp;nativeLoadUrl(String&nbsp;url);</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">&nbsp;&nbsp;&nbsp;&nbsp;调用：</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nativeLoadUrl(url);</span></p>          <h1><span style="font-family: '宋体'; font-size: 12pt; font-weight: normal;">JNI<span style="font-family: 宋体;">层调用</span><span style="font-family: Arial;">Java</span><span style="font-family: 宋体;">函数：</span></span></h1>  <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;Download::transportUrl(WebCore::FrameView*&nbsp;view,&nbsp;WebCore::String&nbsp;url)</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;{</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WebViewCore*&nbsp;viewcore&nbsp;=&nbsp;WebViewCore::getWebViewCore(view);</span></p>  <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JNIEnv*&nbsp;env&nbsp;=&nbsp;JSC::Bindings::getJNIEnv();</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jstring&nbsp;jUrl&nbsp;=&nbsp;&nbsp;env-&gt;NewString(url.characters(),&nbsp;url.length());</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">//&nbsp;</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 12pt; font-weight: bold;">1.&nbsp;</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 12pt; font-weight: bold;">获得Java该类的&nbsp;jclass对象</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jclass&nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt; font-weight: bold;">mODP&nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">=&nbsp;env-&gt;FindClass("archermind/webkit/Observor/ODP");</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">//&nbsp;</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 12pt; font-weight: bold;">2.&nbsp;通过该对象，取得相应java函数及参数到&nbsp;-&gt;&nbsp;jmethodID中</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmethodID&nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt; font-weight: bold;">msendDownloadRequest&nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">=&nbsp;env-&gt;GetStaticMethodID(</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt; margin-left: 36pt;"><span style="font-family: 'Times New Roman'; color: #ff9900; font-size: 12pt; font-weight: bold;">mODP</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">,&nbsp;"</span><span style="font-family: 'Times New Roman'; color: #ff9900; font-size: 12pt; font-weight: bold;">sendDownloadRequest</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">",&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "(</span><span style="font-family: 'Times New Roman'; color: #ff9900; font-size: 12pt; font-weight: bold;">Larchermind/webkit/core/WebView;Ljava/lang/Strin</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">g;)V");</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">//&nbsp;</span><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 12pt; font-weight: bold;">3.&nbsp;在JNI层中，通过函数调用CallStaticVoidMethod来调用java函数。</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;</span><span style="font-family: 'Times New Roman'; font-size: 12pt; font-weight: bold;">CallStaticVoidMethod</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">(mODP,&nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt; font-weight: bold;">msendDownloadRequest</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">,&nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt; font-weight: bold;">viewcore-&gt;getWebViewJavaObject()</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">,</span><span style="font-family: 'Times New Roman'; font-size: 12pt; font-weight: bold;">jUrl</span><span style="font-family: 'Times New Roman'; font-size: 12pt;">);</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">//&nbsp;</span><span style="font-family: 'Times New Roman'; font-size: 12pt; font-weight: bold;">viewcore-&gt;getWebViewJavaObject()&nbsp;为&nbsp;arg1&nbsp;.</span></p> <p style="margin-top: 0pt; text-indent: 36pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt; font-weight: bold;">//&nbsp;jURL&nbsp;为arg2&nbsp;.</span></p> <p style="margin-top: 0pt; margin-bottom: 0pt;"><span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;DeleteLocalRef(jUrl);</span></p> <span style="font-family: 'Times New Roman'; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div><br />转自：http://blog.csdn.net/weiyouyin/article/details/5739659<img src ="http://www.cppblog.com/finehai/aggbug/171757.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-17 15:58 <a href="http://www.cppblog.com/finehai/archive/2012/04/17/171757.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android的系统架构</title><link>http://www.cppblog.com/finehai/archive/2012/04/17/171724.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Tue, 17 Apr 2012 02:59:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/17/171724.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/171724.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/17/171724.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/171724.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/171724.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt;"> </span><div>&nbsp;&nbsp; &nbsp;&nbsp; <span style="font-size: 12pt;">Android的系统架构和其操作系统一样，采用了分层的架构。从架构图看，android分为四个层，从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。</span><br /><br /> <span style="color: #3333ff; font-size: 12pt;">1.应用程序<br /><br /> </span><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; Android会同一系列核心应用程序包一起发布，该应用程序包包括email客户端，SMS短消息程序，日历，地图，浏览器，联系人管理程序等。所有的应用程序都是使用JAVA语言编写的。</span><br /><br /> <span style="color: #3333ff; font-size: 12pt;">2.应用程序框架<br /><br /> &nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 12pt;">  开发人员也可以完全访问核心应用程序所使用的API框架。该应用程序的架构设计简化了组件的重用;任何一个应用程序都可以发布它的功能块并且任何其它的  应用程序都可以使用其所发布的功能块(不过得遵循框架的安全性限制)。同样，该应用程序重用机制也使用户可以方便的替换程序组件。</span><br /><span style="font-size: 12pt;"> 隐藏在每个应用后面的是一系列的服务和系统, 其中包括;</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * 丰富而又可扩展的视图(Views)，可以用来构建应用程序， 它包括列表(lists)，网格(grids)，文本框(text boxes)，按钮(buttons)， 甚至可嵌入的web浏览器。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * 内容提供器(Content Providers)使得应用程序可以访问另一个应用程序的数据(如联系人数据库)， 或者共享它们自己的数据</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * 资源管理器(Resource Manager)提供 非代码资源的访问，如本地字符串，图形，和布局文件( layout files )。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * 通知管理器 (Notification Manager) 使得应用程序可以在状态栏中显示自定义的提示信息。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * 活动管理器( Activity Manager) 用来管理应用程序生命周期并提供常用的导航回退功能。</span><br /><span style="font-size: 12pt;"> 有关更多的细节和怎样从头写一个应用程序，请参考 如何编写一个 Android 应用程序.</span><br /><br /> <span style="color: #3333ff; font-size: 12pt;">3.系统运行库<br /><br /> </span><span style="font-size: 12pt;"> 1)程序库</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; Android 包含一些C/C 库，这些库能被Android系统中不同的组件使用。它们通过 Android 应用程序框架为开发者提供服务。以下是一些核心库：</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * 系统 C 库 - 一个从 BSD 继承来的标准 C 系统函数库( libc )， 它是专门为基于 embedded linux 的设备定制的。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * 媒体库 - 基于 PacketVideo OpenCORE;该库支持多种常用的音频、视频格式回放和录制，同时支持静态图像文件。编码格式包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG 。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * Surface Manager - 对显示子系统的管理，并且为多个应用程序提 供了2D和3D图层的无缝融合。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * LibWebCore - 一个最新的web浏览器引擎用，支持Android浏览器和一个可嵌入的web视图。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * SGL - 底层的2D图形引擎</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * 3D libraries - 基于OpenGL ES 1.0 APIs实现;该库可以使用硬件 3D加速(如果可用)或者使用高度优化的3D软加速。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; * FreeType -位图(bitmap)和矢量(vector)字体显示。   </span><p><span style="font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp; * SQLite - 一个对于所有应用程序可用，功能强劲的轻型关系型数据库引擎。</span><br /><span style="font-size: 12pt;"> 2)Android 运行库</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; Android 包括了一个核心库，该核心库提供了JAVA编程语言核心库的大多数功能。</span><br /><span style="font-size: 12pt;">  每一个Android应用程序都在它自己的进程中运行，都拥有一个独立的Dalvik虚拟机实例。Dalvik被设计成一个设备可以同时高效地运行多个  虚拟系统。  Dalvik虚拟机执行(.dex)的Dalvik可执行文件，该格式文件针对小内存使用做了优化。同时虚拟机是基于寄存器的，所有的类都经由JAVA编  译器编译，然后通过SDK中 的 &#8220;dx&#8221; 工具转化成.dex格式由虚拟机执行。</span><br /><span style="font-size: 12pt;"> &nbsp;&nbsp;&nbsp;&nbsp; Dalvik虚拟机依赖于linux内核的一些功能，比如线程机制和底层内存管理机制。</span></p><p><br /> <span style="color: #3333ff; font-size: 12pt;">4.Linux 内核</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: 12pt;"><br /></span></p><p>&nbsp;&nbsp; &nbsp;&nbsp; <span style="font-size: 12pt;">Android 的核心系统服务依赖于 Linux 2.6 内核，如安全性，内存管理，进程管理， 网络协议栈和驱动模型。 Linux 内核也同时作为硬件和软件栈之间的抽象层。</span></p></div><img src ="http://www.cppblog.com/finehai/aggbug/171724.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-17 10:59 <a href="http://www.cppblog.com/finehai/archive/2012/04/17/171724.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】Ubuntu下安装Android模拟器</title><link>http://www.cppblog.com/finehai/archive/2012/04/11/170876.html</link><dc:creator>Bluesea</dc:creator><author>Bluesea</author><pubDate>Wed, 11 Apr 2012 02:59:00 GMT</pubDate><guid>http://www.cppblog.com/finehai/archive/2012/04/11/170876.html</guid><wfw:comment>http://www.cppblog.com/finehai/comments/170876.html</wfw:comment><comments>http://www.cppblog.com/finehai/archive/2012/04/11/170876.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/finehai/comments/commentRss/170876.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/finehai/services/trackbacks/170876.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 如果你想在自己的PC机上玩玩Adroid，不妨按下列步骤试一试：<br><br>前提：已安装Java平台。&nbsp;&nbsp;<a href='http://www.cppblog.com/finehai/archive/2012/04/11/170876.html'>阅读全文</a><img src ="http://www.cppblog.com/finehai/aggbug/170876.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/finehai/" target="_blank">Bluesea</a> 2012-04-11 10:59 <a href="http://www.cppblog.com/finehai/archive/2012/04/11/170876.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>