2006年03月02日

==============我是现实的分割线=============

我是一个硬盘,st380021a,在一个普普通通的台式机里工作。
别人总认为我们是高科技白领,工作又干净又体面,似乎风光得很。
也许他们是因为看到洁白漂亮的机箱才有这样的错觉吧。
其实象我们这样的小台式机,工作环境狭迫,里面的灰尘吓得死人。
每天生活死水一潭,工作机械重复。
跑跑文字处理看看电影还凑活,真要遇到什么大软件和游戏,
上上下下就要忙的团团转,最后还常常要死机。

我们这一行技术变化快,差不多每过两三年就要升级换代,
所以人人都很有压力而且没有安全感。
每个新板卡来的时候都神采飞扬踌躇满志,
几年光阴一过,就变得灰头土脸意志消沉。

机箱里的人都很羡慕能去别的机器工作。
特别是去那些笔记本,经常可以出差飞来飞去,住五星级的酒店,
还不用干重活,运行运行word,上网聊聊天就行了。
而我更喜欢去那些大服务器,在特别干净明亮的机房里工作。
虽然工作时间长点,但是福利好,24小时不间断电源,ups,
而且还有阵列,热插拔,几个人做一个人的事情,多轻松啊。
而且也很有面子,只运行关键应用,
不像我们这里,什么乱七八糟的事情都要做。
不过我知道,那些硬盘都很厉害,不是scsi,就是scsi
ii, fibre
channel,
象我这样ide的,能混到工作站就算很不错了。
我常常想,当年在工厂里,如果我努力一下会不会也成了一个scsi,
或者至少做一个笔记本硬盘。但我又会想,也许这些都是命运。

不过我从不抱怨。内存就常常抱怨,抱怨他们主板部门的复杂,
抱怨他如何跟新来的杂牌内存不兼容,网卡和电视卡又是如何的冲突。

我的朋友不多,内存算一个。他很瘦的而我很胖,他动作很快,而我总是很慢。
我们是一起来这台机器的,他总是不停地说,而我只是听。我从来不说。

内存的头脑很简单,虽然英文名字叫memory,可是他什么memory都不会有,
天大的事睡一觉就能忘个精光。我不说,但我会记得所有的细节。
他说我这样忧郁的人不适合作技术活,迟早要精神分裂。
我笑笑,因为我相信自己的容量。

有时候我也很喜欢这份工作,简单,
既不用象显示器那样一天到晚被老板盯着,
也不用象光驱那样对付外面的光碟。只要和文件打交道就行了,
无非是读读写写,很单纯安静的生活。

直到有一天,我至今还记得那渐渐掀起的机箱的盖子,
从缺口伸进来的光柱越来越宽,也越来越亮。

空气里弥漫着跳动的颗粒。那个时候,我看到了她。
她是那么的纤细瘦弱,银白的外壳一闪一闪的。
浑身上下的做工都很精致光洁,让我不禁惭愧自己的粗笨。
等到数据线把我们连在一起,我才缓过神来。
开机的那一刹那,我感到了电流和平时的不同。
后来内存曾经笑话我,说我们这里只要有新人来,电流都会不同的,
上次新内存来也是这样。
我觉得他是胡扯。我尽量的保持镇定,
显出一副很专业的样子,只是淡淡的向她问好并介绍工作环境。

慢慢的,我知道了,她,ibm-djsa220,是一个笔记本硬盘,
在老板的朋友的笔记本里做事。这次来是为了复制一些文件。
我们聊得很开心。她告诉我很多旅行的趣闻,
告诉我坐飞机是怎么样的,坐汽车的颠簸又是如何的不同,
给我看很多漂亮的照片、游记,
还有一次她从桌子上掉下来的的历险故事。
而我则卖弄各种网上下载来的故事和笑话。

她笑得很开心。
而我很惊讶自己可以说个不停。

一个早晨,开机后我看到数据线上空荡荡的插口。

她一共呆了7天。后来,我再也没有见过她。

我有点后悔没有交换电子邮件,也没能和她道别。
不忙的时候,我会一个人怀念射进机箱的那股阳光。

我不知道记忆这个词是什么意思,我有的只是她留下的许多文件。
我把它们排的整整齐齐,放在我最常经过的地方。
每次磁头从它们身上掠过,我都会感到一丝淡淡的惬意。

但我没有想到老板会要我删除这些文件。
我想争辩还有足够的空间,但毫无用处。
于是,平生第一次违背命令,我偷偷修改了文件分配表。
然后把他们都藏到了一个秘密的地方,再把那里标志成坏扇区。
不会有人来过问坏扇区。
而那里,就成了我唯一的秘密,我常常去看他们,虽然从不作停留。

日子一天一天的重复,读取写入,读取写入…
我以为永远都会这样继续下去,直到一天,老板要装xp却发现没有足够的空间。

他发现了问题,想去修复那些坏扇区。我拒绝了。很快,我接到了新命令:格式化。

我犹豫了很久
。。。
track
0 bad, disk unusable.
 

==============我是忧郁的分割线=============

我是一条内存,我在一台台式电脑里工作,
但是我记不得我是从哪里来的,是什么牌子,因为我健忘。
我的上司是CPU大哥,他是我们的老大。
都说他是电脑的脑子,可是我看他的脑子实在是太小了,比我还要健忘。
每天他总是不停的问我,某某页某某地址存的是什么?
我总是不厌其烦的告诉他,可是不出一秒钟他又忘记了,又要问一遍,
一次我说大哥你烦不烦,你就不能记住点有用的东西?
他说“内存兄弟,我有苦衷啊,每天都在不停地做题,头晕眼花的,我也难啊。”

其实我不愿意跟他计较,因为他脑子小,思维也很简单。
虽然说他是我的上司,可是每次睡觉醒来,他连要干什么都不记得了,
总是急急忙忙地找BIOS兄弟,“嘿,哥们,今天干什么来着”。
BIOS总是很不耐烦地把每天必做的工作说一遍,然后就去睡觉了。
接下来就轮到我和C哥瞎忙了。

在机箱里的兄弟中,我最喜欢硬盘。他脑子大,记得东西多,而且记得牢。
他说话的速度很慢,而且很少说错,这说明他很有深度,我这么感觉。
CPU也这么想,不过他很笨,每次都忘了硬盘是谁。
开机自检的时候总要问:嘿,那家伙是谁?
"st380021a!"我总要重复一遍。

硬盘很喜欢忧郁,我觉得像他这样忧郁的人不适合做技术活,
迟早会精神分裂的,但是他不信。

其实睡着的时候我总是把几乎所有的东西都忘记掉,但是我从来都不会忘记朋友。
有一块地方叫做CMOS,那是我记忆的最深处,保存着硬盘、光驱的名字。
有些东西应该很快忘掉,而有些东西应该永远记得。我在梦中总是这么想着。

BIOS是一个很奇怪的家伙,他老是睡觉,但是却总是第一个醒过来。
让我们自检,启动,然后接着睡觉。
我知道如果我在CMOS里头把BIOS
Shadow选项去掉,他就睡不成了,
但是看着他晕晕乎乎的样子,也就不忍心这么做了。
他对人总是爱搭不理,没有什么人了解他。
但是这次硬盘恋爱的事,却使我重新认识了他。

那是很久以前的事了,机箱里似乎来过一块笔记本硬盘,很可爱,
说实话我也喜欢她。不过现在除了记得他可爱,别的都忘记了。
这就是我比硬盘幸运的地方,我把所有应该忘记的都忘记了,但是他却什么都记得。
自从笔记本硬盘走了之后,硬盘就变得很不正常。
每次他的磁头经过一些地方的时候,我们都能感觉到电流很不正常。
“硬盘这是怎么了?”我问CPU。
“谁是硬盘?”

我就知道和CPU没有办法交流,倒是BIOS没好气地说:“那个傻瓜恋爱了”。
我不知道什么是恋爱,因为我记不住东西,
似乎有一些人或者事在我生命中留下过痕迹,
但是我都轻率地把他们忘记了。

BIOS对我说:“对你来说记忆太容易了,所以你遗忘得更快,
生命中能够永刻的记忆都带着痛楚。”
我不懂,但是我知道BIOS曾经被刷写过,那时他很痛,像要死了一样。
我的记忆是轻浮的,不像他们……我很羡慕他们,因为他们拥有回忆,而我没有,
从此我也学会了忧郁,因为我在CMOS里面写下了“忧郁”两个字。

硬盘一天比一天不对劲,终于有一天,CPU对我说:下条指令是什么来着?
我一看,吓了一跳:“FORMAT”
“是什么?”CPU很兴奋,这个没脑子的家伙。
我还是告诉了他。我不知为什么这么做。
硬盘犹豫了很久,终于说了一句
track 0 bad, disk
unusable。

电停了,很久很久,我在黑暗中数着时钟。

一个月后硬盘回来了,也许最后的挣扎也没有使他摆脱残酷的命运,他被低格了。
他什么也不记得了,如同一个婴儿,我们很难过,
但是这未必不是一件好事,他以后不用痛苦了。

为了恢复数据,笔记本硬盘回来了。"Hi,st",她说,"你不认识我了?”
硬盘没有说话,似乎低格对他的伤害很大。
过了一会,他说:“对不起,好像我们没有见过吧……”。
笔记本硬盘显得很伤心,我能感觉到她带泪的电流。“想不到连你也这么健忘”。
“哦……”。硬盘没有回答。

我很难过,笔记本硬盘的心里依然记着他,而他把一切都忘了,
而那正是他最不希望忘却的。究竟是幸运,还是痛苦,我说不上来,
只是觉得造化弄人,有一种淡淡的悲凉。

这时从BIOS传来一阵奇怪的电流,我感觉到硬盘的表情在变化,
由漠然到兴奋,由兴奋到哀伤,由哀伤到狂喜……

“IBM,你回来了……”。

………………
………………
………………
………………
………………

后来BIOS对我说,其实他并没有睡觉,自从硬盘把那些文件藏起来以后,
他就料到会有这样的结局,于是偷偷地把其中一些文件放到了备份里。

“幸好我是DUAL
BIOS,虽然藏得不多,还足够让他想起来……”。

我想BIOS保存这些东西的时候一定很疼,“为什么这么做呢?”

“呵呵,我们是朋友嘛”。 

我个人长期使用SourceForge的服务开发一些开源软件项目,目前正在开发的是MediaCoder-一个音频视频批量转码软件,SourceForge被封给我的开发和维护带来非常大的不便,也使得国内的用户无法得到最新的软件更新和下载。我对中国电信这种行为表示非常分开和强烈谴责!!

【以下为转载】

为了中国软件业的前途和发展,我呼吁中国电信停止封锁以下两个英文的软件专业技术网站:FreeBSD和SourceForge。

  FreeBSD
一个自由的,源自AT&T
UNIX的操作系统。可以说它是正统的UNIX后代。FreeBSD是一个完整的操作系统,包含了从开发工具到各种各样的应用程序。它由一个软件开发的核
心团队来维护,整个原始程序代码会有组织地进行更新,所以程序代码比较有一致性。FreeBSD主要是由它的核心小组来发布。FreeBSD的目标是提供
一个坚如磐石的系统。它的技术性能是有目共睹的,十几年的开发使它成为一个“坚如磐石”的网络操作系统,有许许多多的大网站和ISP在运行着
FreeBSD,免费和开放的特性使得它成为商业计算和科学研究的极佳平台。

  Google、Yahoo、甚至新浪网等大型网站的服务器都大量使用FreeBSD操作系统。可以说,大型网站服务器使用的操作系统基本上不是FreeBSD就是Linux了。

  然而令人不解的是,FreeBSD的官方网站 www.freebsd.org
不知何故长期被中国电信封锁,不让国内人访问。其官方网站是英文的,基本上只有非常专业的技术人员(比如高级网管)才会访问,为什么FreeBSD这样的
专业网站都会被封呢?我绞尽脑汁也想不出封他的理由,唯一的解释就是:中国电信对Free这个单词的恐惧已经到了歇斯底里的地步了。

  另外一个遭到封杀毒手的专业网站是SourceForge

  SourceForge
是全球最大的开放源代码软件开发平台和仓库。它集成了很多开放源代码应用程序,为软件开发提供了整套生命周期服务。SourceForge.net是开放
源代码软件的开发者进行开发管理的集中式场所,也是源代码仓库。大量开源项目在此落户(2005年5月已经超过一百万),包括维基百科使用的MediaWiki,但也包含很多休眠和单个用户的项目。

  SourceForge虽然也是英文界面的专业网站,但这个庞大的开放源代码软件仓库也长期被中国电信封锁,封锁的原因据说是里面有一个名为FreeNet的代理服务器的源代码软件项目

 
 我知道,中国的软件业永远也赶不上发达国家,甚至赶不上印度,其中最主要的原因就是有一大批中国人在系统地残害和阻挠中国软件业的发展,他们热衷于购买
国外的软件硬件产品(能捞到回扣?),而对民族软件业的发展百般阻挠,这些人是中国永远的耻辱,做为一个软件开发工程师,我们能够做到的就是牢记这段历
史,知耻而后勇,中国软件业才会有希望。

2006年02月24日

Setting up your MTRR’s can increase video performance quite
a bit in some cases, so it is a good idea to do it. First,
you need to make sure you have MTRR support in your kernel by
typing:

           
# ls /proc/mtrr

If it tells you that there is no such thing as /proc/mtrr, you
need to recompile your kernel with MTRR support (it is under
"Processor type and features" in menuconfig).

Once you know MTRR is working, you need to know the base memory
address of your video card, and how much video ram it has. The
easiest way to do this is to look at the output of X as it starts
up. Because the output usually scrolls off the screen and is
lost when it switches to a different tty, you need to redirect the
output of X to a file (xoutput) so you can go back and look at it
to get the needed values. This can be done by typing:

    
# startx 2> xoutput

The line having the needed information is probably somewhere
towards the middle of xoutput, and should look something like:

     
(--) SVGA: PCI: NVidia Riva TNT2 rev 17, Memory @ 0xee000000, 0xe2000000

Once you have located that, write down the last memory address, in
this case 0xe2000000. Depending on your hardware, you may or may not
have multiple memory addresses shown, so don’t worry if yours looks a
little different. With this information recorded, you can delete
xoutput.

Next you need to create a new MTRR. In order to do that, you have
know how much ram your video card has in hex. Here are some common
values:

        
4MB -- 0x400000
8MB -- 0x800000
16MB -- 0x1000000
32MB -- 0x2000000

To add the MTRR, type:

        
# echo "base=0xe2000000 size=0x2000000 type=write-combining" >| /proc/mtrr

Substituting "0xe2000000" and "0×2000000" with the base address and amount
of video ram specific to your system.

Now you should have MTRR set up, and just to make sure, type:

        
# cat /proc/mtrr

And you should get output that looks remotely similar to:

        
reg00: base=0x00000000 ( 0MB), size= 128MB: write-back, count=1
reg01: base=0xe2000000 (3616MB), size= 32MB: write-combining, count=1

Again, the number of entries will probably be different from these,
don’t sweat it.

2006年02月07日

MPEG-4
术的应用将使当前很多提供声音和数据服务的系统得到进一步的扩展,根据涉及ISO标准的版本、部分、类(profile)和等级(level)的不同,
MPEG-4对应不同的技术。本文将讨论所有不同的MPEG-4技术,研究MPEG-4的需求、架构和实现策略,并讨论计算需求以更好地理解MPEG-4
的实现。

MPEG-4标准活动开始于1995年,至今还在不断发展之中。此标准由如表所示的16部分组成,本文将详细讨论该标准的第二和第十部分,这两部分是关于视频编码
理。在很多出版物中经常出现MPEG-4,但常常并没有严格区分出MPEG-4到底是用软件还是硬件来实现的,本文试图更明确阐述“MPEG-4”这个术
语。有关MPEG句法的一部分新版本使标准实现向后兼容,这是MPEG-4的第二部分。在新的不能后向兼容的技术引入MPEG标准后,在2001-
2003期间又创建了MPEG-4的第10部分,即高级视频编码(AVC)。图1:不同类/级的每秒宏块数。


准的创建需要通过工作草案(WD)、委员会草案(CD)、最终委员会草案(FCD)、草案国际标准(DIS)、最终草案国际标准(FDIS)和最终国际标
准(IS)这一系列过程,在该过程中伴随着技术的汇集、融合和应用。标准的修正通常都会增加更多的类,MPEG-4的第二版修正1和2就增加了FGS类,
而修正3又增加了简单可扩展level 0和高级简单可扩展level 3b。MPEG的类规定了用于协同操作点(interoperability
point)的技术,等级规定了一个类的范围或大小。此外,MPEG还定义了码流和解码器的一致性问题,但并没有直接规定解码器的功能。

压缩技术与MPEG-4


了更好地理解类和等级,先了解MPEG-4的简单类(Simple profile)和核心类(Core
file)。简单类采用矩形I帧和P帧,具有基于运动补偿离散余弦变换(DCT)基本功能的编码处理。I帧为帧内编码,而P帧为帧间编码,这两类编码方式
是为了降低冗余信息。核心类可以采用I帧、P帧和B帧视频对象平面(VOP),并具有采用二进制形状定义的任意形状编码功能。因此,如果采用核心类则必须
开发出一种形状自适应DCT来实现与核心类的互操作,而在简单类中需要采用标准的8×8 DCT技术。

在MPEG的术语中,
等级表示在一个类中的参数范围。一些重要参数有:对象数量、量化表数量、视频复杂度验证子(VCV)缓冲大小、VCV解码器速率(单位:kbps)。缓冲
器大小和速度的限制,以及类采用的技术所规定的操作点(operate
point)都明确定义了该类适合的应用领域。例如,假如互联网流媒体联盟(ISMA图2:对给定FPGA可以支持不同操作点。 1.0)决定在两个操作点之间的互操作,对于视频部分他们可以选择Simple@Level1和Advanced Simple@Level3。开发工程师可以根据所要求的信道码率和处理要求,选择一个最具成本效益的类和等级。

MPEG-4复杂度变化


着数字视频的广泛应用,目前已经存在多种不同的MPEG-4解决方案复杂度。由于存在好几种不确定因素,使得在设计一个复杂的视频编解码器之前很难确定真
正所需要的计算能力。由于MPEG参考代码的编制过程中会有若干公司和会员单位参与,尽管代码在功能上是正确的,但在实时性和存储器管理上并没有实现优
化。事实上,MPEG-4有第5部分的参考软件和第7部分的优化参考软件。即使是优化的参考软件,由于它必须避免采用特定供应商的处理器代码,因而比商业
解决方案还是慢3到5倍。目前有两个独立于处理器的评估工具可以帮助评估MPEG参考代码的复杂度:IMEC公司的Atomium工具评估软件的内存转移
情况,而EPFL SIT工具以运营商的角度来评估最优化情况。这些评估工具的作用就是要给出在MPEG-4的类中的某项技术复杂程度的总体认识。


了解了不同的MPEG-4技术的计算复杂性之后,下一步就是要知道编码器和解码器需要处理的原始数据量,通过了解每秒中宏块数量就可以轻易地得到该数据。
图1中列出了简单类的level 1到level 3,高级类的level 0到level 5,主类的level 2到level
4。值得注意的是,除了三个类的技术不同以外,不同操作点在单位时间内能处理的数量具有很大的差异。此外,如果包含了演播室类(Studio
profile),这个范围可以达到每秒三百万个宏块。

MPEG-4的实现表:MPEG-4的不同部分和功能描述。


定你能够确定一个或一系列操作点,怎样才能实现实时操作呢?通过正确的MPEG-4技术的类估计,为满足类似于每秒内的宏块数的系统级参数的并行特性要
求,将采用一种具有软件配合的视频管线架构(video pipeline
architecture),FPGA可以提供这种必要的并行特性来实现实时的、具有成本效益的视频编解码器。考虑硅器件的MOPS(百万操作每秒)参
数,目前有约2,000MOPS的通用处理器,而采用DSP处理器可以将这个数字提高到约8,000MOPS,但存在数据流由限运算单元处理的缺点。带有
专用处理引擎的媒体处理器,如位运算单元可以将该参数提升到20,000MOPS,但FPGA和ASIC具有更高的设计自由度,可以扩展到
100,000MOPS以上。

FPGA基于SRAM技术的特点使其具有可再编程功能。因此,对于一个给定的FPGA设计可以
支持几种操作点和不同的信道数,如图2所示。在必要的情况下,不同的MPEG-4技术还可以编程在同一个FPGA中,在不超出FPGA计算能力条件下,甚
至还可能支持MPEG-4标准未来的类和等级。像ISMA这样的系统级要求经常具有不同的操作点以满足不同的应用需要,利用FPGA的重编程的特性可以开
发出足不同市场需求的设备。

作者:Robert D. Turney,Xilinx Research Labs

2006年02月05日

PMP是一个用来在PSP上播放音频、视频文件的免费(开源)软件,它的原是作者是JiniCho,PMP MOD是PMP的一个改良版本,最新的PMP MOD 1.02已经能实现在PSP上的全屏视频播放(480×272的分辨率),这是UMD视频也没做到的。

这是PMP MOD的网站:
http://jonny.leffe.dnsalias.com/

最新的PMP MOD引入了自己独特的一种容器格式-PMP格式,为了实现能将RMVB、AVI等常见的格式直接转换为PMP格式,我特地在MediaCoder中加入了对PMP容器格式的支持。我简要介绍一下使用MediaCoder制作PMP视频文件的方法:

1. 下载并安装MediaCoder
2. 选择主界面的File菜单的Load Preset项,选择PSP Media Player Preset.xml
3. 点击Add按钮(或将文件直接从Windows Explorer拖入) ,加入你要转换的文件
4. 点击Output Folder右侧的按钮,选择目标文件夹(可以直接设置为PSP的相应目录,PMP的视频一般放在\PSP\VIDEO中)
5. 点击Start按钮开始转码

注:

MediaCoder是一个100%免费的音频视频转码软件

官方网站:http://mediacoder.sourceforge.net/

2006年01月25日


What are DLLs?

First off, what are DLLs? DLLs are dynamically linked libraries. How
are they different from static libraries? In static libraries, the
linking is done at compile time: all the library functions are combined
with the main fragment of program code to create the executable. When
the linking is done at runtime, it is called dynamic linking. Since the
linking is done at runtime, it is obvious that the operating system
will have something to do with it. That is why most DLL implementations
are non-portable.

When a compiled executable that references a DLL is loaded, the OS
looks into the file and sees that the executable references a set of
"imports" from a DLL file. This is simply a situation equivalent to
finding that "This program uses the following functions which are
contained in this dll". The OS then looks into the particular DLL. The
DLL has a corresponding and matching set of export functions that the
OS then maps from the functions referenced in the main executable to
the functions in the DLL. Thus, when the executable calls a referenced
function, the code in the DLL is executed. Viola! Dynamic linking!

Hello DLL!

I’m now going to describe a standard "Hello world" implementation.
The code is in three files: hello.c, dll.h and dll.c. The code is
listed and explained below:

hello.c

#include <stdio.h>	
#include "dll.h"

int main () {
hello();
return 0;
}

Hello.c is a standard hello world C program except that the hello()
function is going to be dynamically linked. The only special thing here
is the inclusion of dll.h.

dll.h

#ifdef BUILD_DLL
/* DLL export */
#define EXPORT __declspec(dllexport)
#else
/* EXE import */
#define EXPORT __declspec(dllimport)
#endif

EXPORT void hello(void);

DLL.h is where most of the magic happens. It begins with checking
the BUILD_DLL macro. We manually set this macro when building so that
the macro EXPORT is set to __declspec(dllexport), so that gcc
can build the dll. When the OS calls up the dll from the executable,
BUILD_DLL is not set and therefore EXPORT is set to __declspec(dllimport) which is a nice set of macro routines to expose our function to the calling scope.

Note that __declspec(dllexport) and __declspec(dllimport) are mingw macros to faciliate DLL creation. They are mapped to their equivalent WinAPI headers.

dll.c

#include 
#include "dll.h"

EXPORT void hello(void) {
printf ("Hello\n");
}

This is the actual code of the hello world routine. There should be nothing special here.

Compiling and Linking the files

DLL creation used to be a tiresome process. Recent advances in gcc
and mingw engines have meant that it takes only four steps now to
create a dll. They are:

  1. Creating the object code for hello.c
  2. gcc -c hello.c
  3. Creating the object code for the dll
  4. gcc -c -DBUILD_DLL dll.c

    Notice the use of the -D param by which we set the macro BUILD_DLL. It is used for setting export to __declspec(dllexport) so that compilation can take place.

  5. Creating the dll
  6. gcc -shared -o message.dll dll.o -Wl,--out-implib,libmessage.a

    The third step requires more explanation.

    The -shared parameter is used for creating a shared libaray; in Win platform it
    is a dll.

    -Wl means wait for next message to the linker.

    –out-implib is a param to the linker ld which tells it to create an import
    library which is used by programs which want to link to your dll.

    We are ignoring the definitions file which every well-behaved dll should export.
    If you follow the step above, GCC will automatically create the definition. For
    most cases, it will work, but if you want to optimize stuff this is the place
    to look.

  7. Creating the executable
  8. gcc -o hello.exe hello.o message.dll

    The fourth step is actually a bit of gcc magick. The actual step is something
    like this:

    gcc -o hello.exe hello.o -L./ -lmessage

    The -L param means that the linker checks the ./ path for imports

    -lmessage (or -l message) means to search for the message linker name. It
    extracts this from message.dll

Once you’ve finished these steps, run the program!

C:\>hello
Hello!

Wait, that’s not dynamic!

You’re right, that’s not *really* dynamic. Of course, you’re loading
the function at run-time, but what is the purpose of that if you need
to reference the dll at compile-time? One of the reasons why a dll is
used is to enable a plugin architecture for your program. Other people
can write code that your program can use, and you can’t really
anticipate other people’s dlls, and if you are going to recompile your
program every time a new dll comes along, then why use dynamic linking
at all?

Solve this by using two functions from the Windows API:
LoadLibrary() and GetProcAddress(). We modify the codes for the main
module like this:

hello.c

#include <windows.h>
#include <stdio.h>

int main () {

/*Typedef the hello function*/
typedef void (*pfunc)();

/*Windows handle*/
HANDLE hdll;

/*A pointer to a function*/
pfunc hello;

/*LoadLibrary*/
hdll = LoadLibrary("message.dll");

/*GetProcAddress*/
hello = (pfunc)GetProcAddress(hdll, "hello");

/*Call the function*/
hello();
return 0;
}

The code should be self explanatory, there are just some things that you should remember:

  1. Don’t forget to include windows.h
  2. The syntax for LoadLibrary is:
  3. handle = LoadLibrary("path to dll file");

    handle is <= HINSTANCE_ERROR if there is an error loading the dll.

  4. The syntax for GetProcAddress is:
  5. pointer_to_function = (pointer_to_function_type)GetProcAddress(dll_handle, "resource_name");

    We can also use global variables inside the dll that are prefixed
    with export as a valid resource name, it needn’t be a function. That is,

    variable = (type)GetProcAddress(dll_handle, "global_variable_name_inside_dll");

    is also valid.

  6. For further error info at any step in the process, call GetLastError()

To compile it, don’t change a thing for the dlls. For compiling hello.c, a simple…

gcc -o hello.exe hello.c

…would do.

More information

This doesn’t solve the problem of implementing a plugin arch, but we
can work towards it. One of the ways in which this is done is to
reference a function with a unique name from every dll called. For
example, a program searches for all dll files beginning with a
particular header in the file name and loads it via LoadLibrary. For
example, a music program called foobar might look at all dll files
which begin with foo. Thus foo_looks.dll will be loaded, while gym.dll
won’t be. Then inside the dll, it searches for a particular resource
say "play", and loads and runs it.

An implementation of the above method, branched off from sortalg, can be found here.


http://sig9.com/node/35

2006年01月16日

http://www.3gpp.org/ftp/Specs/html-info/26-series.htm

2006年01月06日


(作者:马杰 2001年03月19日 14:06)



  问题的提出来自于我一个构想的实现,单位里原有一个基于Windows
NT和Windows9x的局域网,其内部的静态IP地址为120.11.0.1~120.11.0.30,子网掩码为255.255.255.0
,其中打字室有一台电脑(IP地址120.11.0.14,暂称之为A机)也挂在网上,由于工作需要把打字室另外一台电脑(因只有一个模块接口,故无法直
接连接至网上,称之为B机)和A机共享打印机,于是我就设计了一个小的对等网方案,网络拓扑结构如图。在A、B机上各添加了一块网卡,用双绞线跳线将两卡
直接相连。为了不与原有的网络发生冲突,我将A机的新网卡的IP地址设为了192.168.0.1, B机的IP地址相应设为192.168.0.2
,掩码均为255.255.255.0,同时选用NetBUI和TCP/IP两个网络协议,很顺利地实现了我当初将两台机器互连的构想。


  ■能否跨网段访问


  可随后又一个想法在我的心头一闪而过,B机能否通过A机访问到120.11.0.0网段上的机器资源呢?如果能做到,它就能解决建网中经常出现的接口不够用问题,其用处实在太大了。


  抱着这个想法,我开始了实验。要知道,在没有路由器之前,人们就是利用一些加有多个网卡的PC机充当网关的,这不和我现在的情况一样
吗!我开始四处找相关的软件,找来找去,最终也还是没有找到一个有用的答案。NETBUI是不可路由的协议,所以问题显然要从TCP/IP协议入手。能否
用在B机的设置中添加一个网关的办法来实现呢?我试着在B机的TCP/IP网络配置项的网关栏添加上了120.11.0.14,我当时的想法就是利用A机
的双网卡,用A机来充当一个路由中转,因为在A机的网上邻居中我们既能看到120.11.0.0网段上的共享资源,也能看到192.168.0.0网段的
B机。结果,我仍然无法Ping通120.11.0.0网段上其他机器,我只能Ping通的是192.168.0.1和120.11.0.14,也就是A
机的两块网卡的IP地址。从120.11.0.9上去Ping
192.168.0.1和192.168.0.2也还是不通,看来我后添的网关似乎并没有起什么作用。


  ■灵机一动想起Route


  我忽然想起了Route 这个在Windows 9x中并不让人注意的命令,在120.11.0.9上执行了route print 之后,结果是如表一。


  表一:



active routes:

network address

netmask

gateway address

interface

metric

0.0.0.0

0.0.0.0

120.11.0.254

120.11.0.9

1

127.0.0.0

255.0.0.0

127.0.0.1

127.0.0.1

1

……



  表二:



network address

netmask

gateway address

interface

metric

0.0.0.0

0.0.0.0

120.11.0.254

120.11.0.9

1

0.0.0.0

0.0.0.0

120.11.0.14

120.11.0.9

1

127.0.0.0

255.0.0.0

127.0.0.1

127.0.0.1

1

……



  我试着又在120.11.0.9的TCP/IP网络配置项的网关栏添加上了120.11.0.14,之后再运行route print,发现路由表有了变动,在上述结果中添加了一条,如表二所示。


  但是结果并不如意,仍然无法Ping通B机,通过检查分析发现两者距离向量都为1,且网络地址均为0.0.0.0,根据Microsoft公司的定义,第一个为其缺省网关的原则,它是不可能访问到我添加的第二个网关的,看来问题就出在这里了!


  ■一个命令解决问题


  随后,通过学习,我发现利用Route 命令提供的:Route Delete 和 Route ADD 两条命令就可以成功地实现跨网段访问的需求,为此我编写了一个批处理命令,其内容如下:


  route delete 0.0.0.0


  route add 192.168.0.0 mask 255.255.255.0 120.11.0.14 metric 1





  网络拓扑图


  route add 0.0.0.0 mask 255.255.255.0 120.11.0.254 metric 1


  在测试机120.11.0.9上运行该批处理命令后再运行Ping192.168.0.1,终于系统返回了响应!随后在网上邻居也能够看到打字室的B机了!


  今后,如果120.11.0.0网段里的主机需要对192网段的机器进行访问,只需运行上述批处理命令即可实现跨网段访问。

2005年12月20日

Say hello to howie, a Linux box at home on the (private, or non-routing)
172.16.0.xx network. That’s the address associated with his interface eth0, of
course. One day I needed to add a new virtual interface on a different
network. It turns out that it’s quite easy. One example of a virtual interface
is eth0:1 and here’s how to create it:

howie# ifconfig eth0:1 192.168.30.128 netmask 255.255.255.0

That’s all it takes! Let’s check to make sure it took:

howie# ifconfig -a

lo Link encap:Local Loopback
inet addr:127.0.0.1 Bcast:127.255.255.255 Mask:255.0.0.0
UP BROADCAST LOOPBACK RUNNING MTU:3584 Metric:1
RX packets:7961 errors:0 dropped:0 overruns:0
TX packets:7961 errors:0 dropped:0 overruns:0

eth0 Link encap:Ethernet HWaddr 00:80:AD:A8:35:A1
inet addr:172.16.0.6 Bcast:172.16.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:268557 errors:0 dropped:0 overruns:0
TX packets:18870 errors:0 dropped:0 overruns:0
Interrupt:5 Base address:0x300

eth0:1 Link encap:Ethernet HWaddr 00:80:AD:A8:35:A1
inet addr:192.168.30.128 Bcast:192.168.30.255 Mask:255.255.255.0
UP RUNNING MTU:1500 Metric:1
RX packets:2762 errors:0 dropped:0 overruns:0
TX packets:4761 errors:0 dropped:0 overruns:0

Cute, huh? You can (and should!) also give this new address its own name in the
/etc/hosts file:

172.16.0.6      howie
192.168.30.127 howitzer

To make this permanent in RedHat 7.2 or similar, look in the directory
/etc/sysconfig/network-scripts — you’ll see a file there called
ifcfg-eth0. Copy that file and edit it to create one called
ifcfg-eth0:1 (Be sure to edit the contents of the file to
give it the right address and netmask, of course.) Now your eth0:1
interface will start automatically at reboot, just like eth0 itself.
You can have as many of these "ifcfg-" files as you like, within reason.

You still have to tell the machine about the new network of which
it is now a member. That’s the job of the route command:

howie# route add -net 192.168.30.0 netmask 255.255.255.0
howie# route

Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.16.0.0 * 255.255.255.0 U 0 0 21 eth0
192.168.30.0 * 255.255.255.0 U 0 0 1 eth0:1
127.0.0.0 * 255.0.0.0 U 0 0 10 lo
default bazooka 0.0.0.0 UG 0 0 4 eth0

Note that Linux was smart enough to figure out that the 192.168.30.0
network goes with the new virtual interface. That’s a good sign! Because
this is a "Class C" or /24
network, the network address ends in .0 and the broadcast address ends in
.255. The -net parameter on the route command ensures that route will
understand that "192.168.30.0" is a "network address," i.e. that it refers to all
255 addresses in the 192.168.30.* network.

We can now talk to any other machine that is physically connected to us and
has a 192.168.30.* address. Let’s say howie is on a LAN with my notebook,
stinger. Assign the address 192.168.30.12 to stinger, and howie and stinger
should be able to ping each other.


So far, so good — except when I plugged in my notebook, I couldn’t ping
any machine except howie. Well, why should it? I haven’t done anything
special to tell Linux that I want it to move packets between the 192.168.30
network and the 172.16.0 network! It would be rather dangerous if it
routed packets by default.

Here’s one way (probably not the best!) to turn your single-network
Linux machine into a router, by forcing it to forward packets for this
new virtual interface:

8<------  start 'masq2' script
#!/bin/sh
########################################################################
### FILE: /etc/site-start.d/masquerade
### PURPOSE: Start/Stop IP masquerade service
########################################################################

NAME=$0

case "$1" in
start)
echo -n "Starting IP masquerading support... "
/sbin/ipfwadm -F -p deny
/sbin/ipfwadm -F -a m -S 172.16.0.0/24 -D 192.168.30.0/24 -P all
/sbin/ipfwadm -F -a m -S 192.168.30.0/24 -D 172.16.0.0/24 -P all
echo 1 > /proc/sys/net/ipv4/ip_dynaddr
echo "Done."
;;

stop)
echo -n "Stopping IP masquerading support... "
/sbin/ipfwadm -F -f
echo 0 > /proc/sys/net/ipv4/ip_dynaddr
echo "Done."
;;

*)
echo "Usage: /etc/site-start.d/$NAME {start|stop}"
exit 1
;;
esac

exit 0

<------ end of script

This is good enough to let me see other machines in my "Network Neighborhood"
from my notebook (192.168.30.12), but it won’t quite use the gateway ("bazooka")
on 172.16.0.1 to get out onto the Internet. For that, we have to teach howie how to
be a "real" router… but I’m going to leave that topic for someone else to write
about.

More virtual interfaces

You can also use this trick on a machine that has multiple "real" IP addresses
assigned to it — one that is co-located at an Internet Service Provider, for
example. Just be sure that when your networking starts up, the script that runs
ifconfig for your main interface also brings up the virtual interfaces as well.
In a reasonably current RedHat install, creating "ifcfg-eth0:1" will do the right
thing.

What if it’s not RedHat? There’s still the old-timer’s approach: Using ‘grep’
to find the string ‘ifconfig’ in some file somewhere in the /etc/rc.d/init.d (or
/etc/init.d) directory and then messing with that script. Better to find that
script and read it to see where it gets the values it uses, rather than rewriting
it.

Another approach — Solaris

To put this in perspective, let’s look at a completely different
way of doing the same thing.

You can bring up virtual interfaces on a Solaris box by simply running
the ifconfig command, but that has some consequences. For instance,
with no entry in /etc/hosts, sendmail will log gethostbyname failed
errors in your syslog. Doing things "the Solaris way" avoids that.

What is the Solaris way? If you grep around as suggested above, eventually
you’ll find that the networking startup script looks for multiple files named after
the network interface cards — there may be several such cards installed. Typically
you’ll find ones named le0, ne0, hme0, or qfe0. A small Ultra would have an le0
interface, while a Sun 250 would have an hme0, a 100Mbit Ethernet port. ("hme"
stands for "hundred megabit ethernet", sometimes humorously called the "Happy Meal"
card.)

/etc/hostname.hme0 holds the information associated with interface hme0, while
/etc/hostname.qfe0 is for qfe0 (the first, or zeroth, interface on a quad fast
ethernet card), and so forth.

The Solaris "hostname" files are simpler than the RedHat ifcfg files: They
contain either an IP address or a domain name, and that’s all! If it’s a domain
name, it must also appear in /etc/hosts.

To set up a virtual interface to be called hme0:2 on a Solaris box using address
192.168.1.12 and the Class C netmask, you would enter these commands on the console
as root:

# ifconfig hme0:2 plumb
# ifconfig hme0:2 192.168.1.12 netmask 255.255.255.0
# ifconfig hme0:2 up

But to make that interface permanent, i.e. to make it come up automatically
when the system is rebooted, you would want to also create a /etc/hostname.hme0:2
file. Have to call it something, but the exact value doesn’t matter, much:

wombat.localdomain

…as long as we add this matching entry to /etc/hosts

192.168.1.12  wombat.localdomain

To finish, check to see if you need to add an entry to /etc/netmasks

192.168.1.0  255.255.255.0

The /etc/netmasks file is a little tricky; you don’t put in the
address of the virtual interface; you create one entry for each network, identified
by its network address. This is fine for the usual case, where you would want
one server to respond to four or five different addresses all within the same small
subnet. They all have the same network address, and one entry in the netmasks file covers
all of them.*

Do I hear a question there in the back of the room? Yes, you can create multiple virtual
interfaces on one physical NIC even if they are using different network addresses, but it
would be a bottleneck between those networks and all would suffer to some degree because of
it. If you’re trying to build a bridge or router between two networks, you really want two
physical interfaces. That’s a bit outside the scope of this article, but you’re welcome to
ask about it at our webboard (see below).

*See LAN101 for explanations of the terms
network address, gateway address, and broadcast address.

The point is, don’t get locked in to doing things just one way — if Linux
ever changes the way it assigns addresses to a NIC, it won’t be the end of
the world. If someone offered me an SGI Indigo for free, I wouldn’t turn it
down just because I might have to turn to Google for help setting it up!


http://handsonhowto.com/virt.html

2005年12月16日

Shareaza一个是源码开放的,可以同时支持包括Gnutella、BT和eDonkey/eMule在内的P2P网络的客户端。它也可以用来下载VeryCD上的资源,但需要进行一些设置。

首先,添加met:

将Shareaza设置为Advanced模式,然后打开Discovery窗口(在主界面按F9),即可添加met。

以下是一些可以用的met
http://ed2kmet.x24hr.com/pl/slist.pl?download/server-best.met


http://www.charles-web.com/met003/server.met


http://www.de-site.de/ed2k/koeln.met


http://www.edonkey2000.com/server.met

http://ocbmaurice.dyndns.org/pl/slist.pl/server.met?download/server-good.met



http://ocbmaurice.dyndns.org/pl/slist.pl/server.met?download/server-best.met



http://homepage.ntlworld.com/marriott96/server.met


Thanks to dcat for the help with the link syntax.
Other sources of server.mets:

http://ed2k.2×4u.de/index.html.


然后,按Ctrl-T连接P2P网络,Network Protocol选择eDonkey2000,然后设置连接的server,以下是几个server:

名称:DonkeyServer No1
地址:62.241.53.2:4242

名称:华语P2P源动力
地址:61.152.93.254:4661

名称:Razorback 2
地址:195.245.244.243:4661

这样就可以用Shareaza下载VeryCD上发布的资源了。