wenjiang 的个人资料morning's blog照片日志列表更多 工具 帮助

日志


10月30日

[转贴]成员函数指针的实现

那么,编译器是怎样实现成员函数指针的呢?这里是对不同的32、64和16位的编译器,对各种不同的数据类型(有int、void*数据指针、代码 指针(比如指向静态函数的指针)、在单一(single-)继承、多重(multiple-)继承、虚拟(virtual-)继承和未知类型 (unknown)的继承下的类的成员函数指针)使用sizeof运算符计算所获得的数据:

编译器

选项

int

DataPtr

CodePtr

Single

Multi

Virtual

Unknown

MSVC

4

4

4

4

8

12

16

MSVC

/vmg

4

4

4

16#

16#

16#

16

MSVC

/vmg /vmm

4

4

4

8#

8#

--

8#

Intel_IA32

4

4

4

4

8

12

12

Intel_IA32

/vmg /vmm

4

4

4

4

8

--

8

Intel_Itanium

4

8

8

8

12

20

20

G++

4

4

4

8

8

8

8

Comeau

4

4

4

8

8

8

8

DMC

4

4

4

4

4

4

4

BCC32

4

4

4

12

12

12

12

BCC32

/Vmd

4

4

4

4

8

12

12

WCL386

4

4

4

12

12

12

12

CodeWarrior

4

4

4

12

12

12

12

XLC

4

8

8

20

20

20

20

DMC

small

2

2

2

2

2

2

2

DMC

medium

2

2

4

4

4

4

4

WCL

small

2

2

2

6

6

6

6

WCL

compact

2

4

2

6

6

6

6

WCL

medium

2

2

4

8

8

8

8

WCL

large

2

4

4

8

8

8

8

注:

# 表示使用__single/__multi/__virtual_inheritance关键字的时候代表4、8或12。

这些编译器是Microsoft Visual C++ 4.0 to 7.1 (.NET 2003), GNU G++ 3.2 (MingW binaries, http://www.mingw.org/), Borland BCB 5.1 (http://www.borland.com/), Open Watcom (WCL) 1.2 (http://www.openwatcom.org/), Digital Mars (DMC) 8.38n (http://www.digitalmars.com/), Intel C++ 8.0 for Windows IA-32, Intel C++ 8.0 for Itanium, (http://www.intel.com/), IBM XLC for AIX (Power, PowerPC), Metrowerks Code Warrior 9.1 for Windows (http://www.metrowerks.com/), 和 Comeau C++ 4.3 (http://www.comeaucomputing.com/). Comeau的数据是在它支持的32位平台(x86, Alpha, SPARC等)上得出的。16位的编译器的数据在四种DOS配置(tiny, compact, medium, 和 large)下测试得出,用来显示各种不同代码和数据指针的大小。MSVC在/vmg的选项下进行了测试,用来显示“成员指针的全部特性”。(如果你拥有在列表中没有出现的编译器,请告知我。非x86处理机下的编译器测试结果有独特的价值。)

 

看着表中的数据,你是不是觉得很惊奇?你可以清楚地看到编写一段在一些环境中可以运行而在另一些编译器中不能运行的代码是很容易的。不同的编译器之 间,它们的内部实现显然是有很大差别的;事实上,我认为编译器在实现语言的其他特性上并没有这样明显的差别。对实现的细节进行研究你会发现一些奇怪的问 题。

一般,编译器采取最差的,而且一直使用最普通的形式。比如对于下面这个结构:

// Borland (缺省设置) 和Watcom C++.

struct {

FunctionPointer m_func_address;

int m_delta;

int m_vtable_index; //如果不是虚拟继承,这个值为0。

};

// Metrowerks CodeWarrior使用了稍微有些不同的方式。

//即使在不允许多重继承的Embedded C++的模式下,它也使用这样的结构!

struct {

int m_delta;

int m_vtable_index; // 如果不是虚拟继承,这个值为-1。

FunctionPointer m_func_address;

};

// 一个早期的SunCC版本显然使用了另一种规则:

struct {

int m_vtable_index; //如果是一个非虚拟函数(non-virtual function),这个值为0。

FunctionPointer m_func_address; //如果是一个虚拟函数(virtual function),这个值为0。

int m_delta;

};

//下面是微软的编译器在未知继承类型的情况下或者使用/vmg选项时使用的方法:

struct {

FunctionPointer m_func_address;

int m_delta;

int m_vtordisp;

int m_vtable_index; // 如果不是虚拟继承,这个值为0

};

// AIX (PowerPC)上IBM的XLC编译器:

struct {

FunctionPointer m_func_address; // 对PowerPC来说是64位

int m_vtable_index;

int m_delta;

int m_vtordisp;

};

// GNU g++使用了一个机灵的方法来进行空间优化

struct {

union {

FunctionPointer m_func_address; // 其值总是4的倍数

int m_vtable_index_2; // 其值被2除的结果总是奇数

};

int m_delta;

};

对于几乎所有的编译器,delta和vindex用来调整传递给函数的this指针,比如Borland的计算方法是:

adjustedthis = *(this + vindex -1) + delta // 如果vindex!=0

adjustedthis = this + delta // 如果vindex=0

(其中,“*”是提取该地址中的数值,adjustedthis是调整后的this指针——译者注)

Borland使用了一个优化方法:如果这个类是单一继承的,编译器就会知道delta和vindex的值是0,所以它就可以跳过上面的计算方法。

GNU编译器使用了一个奇怪的优化方法。可以清楚地看到,对于多重继承来说,你必须查看vtable(虚拟函数表)以获得voffset(虚拟函数 偏移地址)来计算this指针。当你做这些事情的时候,你可能也把函数指针保存在vtable中。通过这些工作,编译器将m_func_address和 m_vtable_index合二为一(即放在一个union中),编译器区别这两个变量的方法是使函数指针(m_func_address)的值除以2 后结果为偶数,而虚拟函数表索引(m_vtable_index_2)除以2后结果为奇数。它们的计算方法是:

adjustedthis = this + delta

if (funcadr & 1) //如果是奇数

call (* ( *delta + (vindex+1)/2) + 4)

else //如果是偶数

call funcadr

(其中, funcadr是函数地址除以2得出的结果。——译者注)

Inter的Itanium编译器(但不是它们的x86编译器)对虚拟继承(virtual inheritance)的情况也使用了unknown_inheritance结构,所以,一个虚拟继承的指针有20字节大小,而不是想象中的16字节。

// Itanium,unknown 和 virtual inheritance下的情况.

struct {

FunctionPointer m_func_address; //对Itanium来说是64位

int m_delta;

int m_vtable_index;

int m_vtordisp;

};

我不能保证Comeau C++使用的是和GNU相同的技术,也不能保证它们是否使用short代替int使这种虚拟函数指针的结构的大小缩小至8个字节。最近发布的Comeau C++版本为了兼容微软的编译器也使用了微软的编译器关键字(我想它也只是忽略这些关键字而不对它们进行实质的相关处理罢了)。

Digital Mars编译器(即最初的Zortech C++到后来的Symantec C++)使用了一种不同的优化方法。对单一继承类来说,一个成员函数指针仅仅是这个函数的地址。但涉及到更复杂的继承时,这个成员函数指针指向一个形式转 换函数(thunk function),这个函数可以实现对this指针的必要调整并可用来调用实际的成员函数。每当涉及到多重继承的时候,每一个成员函数的指针都会有这样 一个形式转换函数,这对函数调用来说是非常有效的。但是这意味着,当使用多重继承的时候,子类的成员函数指针向基类成员函数指针的转换就会不起作用了。可 见,这种编译器对编译代码的要求比其他的编译器要严格得多。

很多嵌入式系统的编译器不允许多重继承。这样,这些编译器就避免了可能出现的问题:一个成员函数指针就是一个带有隐藏this指针参数的普通函数指针。

微软"smallest for class"方法的问题

微软的编译器使用了和Borland相似的优化方法。它们都使单一继承的情况具有最优的效率。但不像Borland,微软在缺省条件下成员函数指针 省略了值为0 的指针入口(entry),我称这种技术为“smallest for class”方法:对单一继承类来说,一个成员函数指针仅保存了函数的地址(m_func_address),所以它有4字节长。而对于多重继承类来说, 由于用到了偏移地址(m_delta),所以它有8字节长。对虚拟继承,会用到12个字节。这种方法确实节省空间,但也有其它的问题。

首先,将一个成员函数指针在子类和基类之间进行转化会改变指针的大小!因此,信息是会丢失的。其次,当一个成员函数指针在它的类定义之前声明的时 候,编译器必须算出要分配给这个指针多少空间,但是这样做是不安全的,因为在定义之前编译器不可能知道这个类的继承方式。对Intel C++和早期的微软编译器来说,编译器仅仅对指针的大小进行猜测,一旦在源文件中猜测错误,你的程序会在运行时莫名其妙地崩溃。所以,微软的编译器中增加 了一些保留字:__single_inheritance, __multiple_inheritance,和 __virtual_inheritance,并增设了一些编译器开关(compiler switch),如/vmg,让所有的成员函数指针有相同的大小,而对原本个头小的成员函数指针的空余部分用0填充。Borland编译器也增加了一些编 译器开关,但没有增加新的关键字。Intel的编译器可以识别Microsoft增加的那些关键字,但它在能够找到类的定义的情况下会对这些关键字不做处 理。

对于MSVC来说,编译器需要知道类的vtable在哪儿;通常就会有一个this指针的偏移量(vtordisp),这个值对所有这个类中的成员 函数来说是不变的,但对每个类来说会是不同的。对于MSVC,经调整过的this指针是在原this指针的基础上经过下面的计算得出的:

if (vindex=0) //如果不是虚拟继承(_virtual_inheritance)

adjustedthis = this + delta

else //如果是

adjustedthis = this + delta + vtordisp + *(*(this + vtordisp) + vindex)

在虚拟继承的情况下,vtordisp的值并不保存在__virtual_inheritance指针中,而是在发现函数调用的代码时,编译器才将 其相应的汇编代码“嵌”进去。但是对于未知类型的继承,编译器需要尽可能地通过读代码确定它的继承类型,所以,编译器将虚拟继承指针(virtual inheritance pointer)分为两类(__virtual_inheritance和__unknown_inheritance)。

理论上,所有的编译器设计者应该在MFP(成员函数指针)的实现上有所变革和突破。但在实际上,这是行不通的,因为这使现在编写的大量代码都需要改 变。微软曾发表了一篇非常古老的文章(http://msdn.microsoft.com/archive/en- us/dnarvc/html/jangrayhood.asp)来解释Visual C++运作的实现细节。这篇文章是Jan Gray写的,他曾在1990年设计了Microsoft C++的对象模型。尽管这篇文章发表于1994年,但这篇文章仍然很重要——这意味着C++的对象模型在长达15年的时间里(1990年到2004年)没 有丝毫改变。

现在,我想你对成员函数指针的事情已经知道得太多了。要点是什么?我已为你建立了一个规则。虽然各种编译器的在这方面的实现方法有很大的不同,但是 也有一些有用的共同点:不管对哪种形式的类,调用一个成员函数指针生成的汇编语言代码是完全相同的。有一种特例是使用了“smallest for class”技术的非标准的编译器,即使是这种情况,差别也是很微小的。这个事实可以让我们继续探索怎样去建立高性能的委托(delegate)。

 

来源:
http://hi.baidu.com/lgr7/blog
http://www.codeproject.com/KB/cpp/FastDelegate.aspx

一段看似BUG的C++代码(适合MSVC,ICC,GCC等一切用户阅读)

最近在写COM的参数dispatch,由于是COM的方法中,参数个数是未知数,我们不可能写出全部的函数类型,所以最终实现时使用堆栈的运用技巧.其中碰到一个很简单又很复杂的问题.
 
看代码
 
class clsA;
typedef void (clsA::*memfunc)(void);
class clsB
{
// memfunc pfn;
 int i;
};
class clsA
{
 clsA();
 int i;
};

int main()
{
 printf("sizeof:%d\n",sizeof(memfunc));
 return 0;
}
在这代码中clsA前置声明,然后声明了成员函数型的,然后声明了ClsB,暂时pfn的成员被注释了,最后完整声明了ClsA,这段代码的打印结果是4,也就是说,此时的memfunc成员函数指针类型的大小是4字节.
 
然后去掉那行注释,再次运行,结果是16~!
然后去掉clsA的前置声明,把后面的完整声明移到顶部,在编译看看结果,又是4~!
 
于是,我们得出以下结论:
前置声明时,其他地方对函数类型指针类型的使用,会导致大小发生变化.
完整声明则不受影响.
 
 
如何解决这个问题呢?
在ClsA的前置声明中加入 __single_inheritance,明确声明这是一个单一继承类,终于情况二也正确返回4字节了
 

从零开始,SDK实现ActiveX

最近在做一个浏览器相关的产品,用的是SDK编程.为了展现flash,网页这类activex(ole的商品名,为了减少打字,下称ole)的控件,该怎么办呢?最简单的办法是使用atl,mfc这样的类库编程,但是这将带来其他的一些问题.依赖的dll增加或lib冲突等.简单但有副作用.
来吧,从零做起,用sdk方式来实现ole的一切.不重复制造轮子是原则,但是搜到几个sdk的例子,但是实现的都很有限.看完这些例子,我实现了第一版的SDK CHtmView,最主要的是了解了ole的一些原理/接口.其实,在安装vc的时候就已经有一个很好的例子供我们参考了,这就是MFC.源码之前了无秘密.当我们使用 CHtmlView 时,想必或多或少都看过它的继承层次.提出以下几个问题,并逐个解决:
1.MFC的ole控件的继承关系(以CHtmlView为例)
在afxhtml.h可以看到
CObject -> CCmdTarget -> CWnd -> CView -> CScrollView -> CFormView -> CHtmlView
2.MFC中ole控件是如何创建的
(这部分涉及很多MFC的文件,所以只写思路了,理清这部分的思路,最佳的方式是亲自阅读一下MFC的代码,你会收益匪浅)
COccManager 作为ole的管理单元,负责ole的创建.每模块都一个COccManager对象.通过它可以创建COleControlContainer(这是site的容器),COleControlSite(这是site,它是控件的容器),而wnd包含了对COccManager的访问,这样当cwnd作为创建者时,它可以很方便的创建ole控件,反过来,所有的mfc窗体又继承自cwnd,作为控件它可以很方便的和容器窗体交互.
在AFX_MODULE_STATE中保存有COccManager* m_pOccManager;当作为容器的site的eventsink收到事件时,会转发给它,它再转发给对应的控件CWnd,控件Cwnd通过事件映射表派发消息,如何派发参数各异的函数调用呢,请阅读 _AfxDispatchCall (很不错的堆栈运用)
容器或管理层次 COccManager -> COleControlContainer -> COleControlSite(对于Html,派生一个CHtmlControlSite,以便实现Html的更多定制) -> CWnd(控件)
事件流向 COleControlSite -> COccManager -> CWnd(控件)

3.我的实现
在问题1中提到了MFC的继承层次,但是作为SDK编程,我们显然不会去把HWND包装成CWND这样肥大无比的东西.
继承关系 CCmdTarget -> COleControl
继承关系 CCmdTarget -> COleControlSite
继承关系 CCmdTarget -> COleControlContainer
容器或管理层次 COccManager -> COleControlContainer -> COleControlSite(派生一个COleDocHostSite,以便实现Html的更多定制) -> COleControl(控件)
事件流向 COleControlSite -> COleControl(控件)
供IE控件使用的的容器(标准容器) COleControlSite -> COleDocHostSite
CCmdTarget 是很多类的基类,其实它的功能很简单,它继承自IUnknown(估计有人看到这个名字就知道CCmdTarget在这里的大概用途了),它具有以下功能,IUnknown的3大标准方法,事件等支持.
大家可能注意到了,事件流向和MFC是不同的,因为我们不打算像MFC那样在 COccManager 处走一次
对于IE
继承关系 COleControl -> CHtmlView
IE站点的继承关系(增加额外特性) COleDocHostSite -> CHtmlControlSite
容器或管理层次 COccManager -> COleControlContainer -> CHtmlControlSite -> CHtmlView
事件流向 COleControlSite -> CHtmlView(控件)
 
 
关键字:
SDK,IE控件,flash控件,activex,COM,OLE,MFC,ATL,WTL
 
demo截图:
untitled
10月24日

virtualbox 中的ubuntu如何安装addon

打开终端
 
输入:
cd ../../cdrom
sudo sh VBoxLinuxAdditons-x86.run

[雷]福建省教育厅:榕中学生设计出双磁头硬盘 获青少年科技创新大赛二等奖

福州第十八中学九年(12)班的邱嘉华设计了一种双磁头硬盘,有望将硬盘的传输速度提高近1倍:给硬盘加一个磁头,再加一条传送带.由于多了一个磁头,读取的面积便扩大了一倍,其传输速度几乎能达到单磁头硬盘两倍.嘉华的这个设计在福州市第23届青少年科技创新大赛上获得了二等奖.

平时,我们用电脑下载、播放、制作、编辑、移动文件及打游戏时,常常因为运行速度慢而耽误了时间,这些都与硬盘的传输速度有关.福州第十八中学九年(12)班的邱嘉华设计了一种双磁头硬盘,有望将硬盘的传输速度提高近1倍.

邱嘉华课余时间很喜欢摆弄电脑.他不仅用电脑上网、打游戏,还痴迷于研究其内部结构.为了了解硬盘的发展过程和工作原理,他不惜将昂贵的硬盘一个个拆开研究.

“我们平时使用电脑时,常常会碰到速度慢、'卡机'等问题,这和硬盘的传输速度有关.提高硬盘的容量和工作效率一直是IT界的研究热点.”嘉华说.

如何提高硬盘的传输速度呢?他研究过几种方法,比如:增加硬盘的盘片、提高大硬盘的转速、做“内存硬盘”等等.但他认为这些都不能从根本上解决问题.

“一块3.5英寸的硬盘,装5张已是上限;其次,如果要提高转速,就会增加硬盘组件的磨损机会、产生噪声;而做'内存硬盘'的成本又太高,昂贵的价格普通用户根本承受不了.”他说.

最后,他想出一个既简易又实用的方法:给硬盘加一个磁头,再加一条传送带.由于多了一个磁头,读取的面积便扩大了一倍,其传输速度几乎能达到单磁头硬盘两倍.

嘉华的这个设计在福州市第23届青少年科技创新大赛上获得了二等奖.目前,他还在对这个设计做进一步实验和完善.

查看:福建省教育厅

10月21日

李一男辞职调查:走出华为的叛逆男人

华为准接班人李一男,沉默两年之后火线换亲加盟百度。就在两年前,他曾以更为悲壮的方式进入华为,那是他第二次走进这家以狼作为图腾的公司。

  像大多数人认为的那样,李一男是个倔强的理想主义者,虽然刻意低调却又不时卷入看不见硝烟的战争。而此次,百度会成为李一男期待的黎明吗?

  与那些同在通信行业前台的人物相比,李一男此次离开华为缺少一个辉煌的告别——与现在华为的告别、与过去港湾的告别,或许也将是与通信行业的彻底告别。但他的离开却是对犬牙交错的通信产业一个最真实的呈现。李一男两次离职华为,潜藏在其中的不仅包括梦想,也包括在商战的残酷中显得单薄而可怜的骄傲和叛逆。

  通信少帅梦断华为

  1992年,正读研究生第二学年的李一男与他的几位同学一起,怀揣着理想进入当时毫不起眼的华为实习。一年之后,这个带着黑色边框眼镜的大男孩正式加盟华为。华为的多位老员工回忆,当时的李一男不爱讲话,但天生的技术敏感让他深得华为高层的赏识。

  “他的确是个技术天才,但在与同事相处的过程中却处处左支右绌。如果是在其他公司,李一男肯定会被排挤出去。”时任华为人力资源部专员的于蓉(应被访者要求,此处隐去真实姓名)如今已不愿轻言往事,记者辗转联系到她时,她已经是一家生产化学试剂公司的人力资源总监。

  “当时在华为明显的气氛是,争论强烈但没有复杂的办公室政治,而且当年的华为确实在任正非的领导下唯才是用,这正是吸引李一男留在华为并能被委以重任的原因。”于蓉在接受记者电话采访时表示,“最明显的例子是,在李一男的思想中根本没有层级制度,在技术和产品方面的见地他常常只跟两个人分享——与他一起进入华为的徐某和任正非本人。这在任何一家国内公司看来都显得有点特立独行的行为方式,却大受任正非喜爱。”

  或许是李一男的技术天赋打动了任正非,1995年,李一男被破格提升为华为总工程师。当时的李一男25岁,当时的华为刚刚推出C&C08 数字程控交换机,在华为历史中颇占份量的华为上海研究院在李一男加盟升任总工后一年才正式成立。

  少年得志的李一男并没有因此改掉骄傲和叛逆的行为方式,“很少对人假以辞色,对其他副总也是态度粗暴,和任正非很相像。这可能源于他的单纯,不知道去了解如何做人,或许压根是不屑于学习。”于蓉向记者回忆李一男的当年。

  有趣的是,李一男对产品和技术发展趋势的把握却总能走在时间前面,因此华为与任正非本人也给了他足够大的发展空间。于蓉表示:“当时,外界议论说李一男身上有太多任正非的影子,任这位华为的开创者和精神领袖用独到、乖张的性格感染了业界,自然也影响了‘不谙世事’的李一男。李在2000年离开华为时,除了与任正非和少数技术主管仍保持顺畅的沟通之外,和大多数其他高管都有不同程度的交恶。这预示了不失才华的李一男今后与华为的曲终人散。”

  2000年,一致被认为是任正非准接班人的李一男携1000万元分红第一次走出华为,踏上深圳飞往北京的航班,华为企业网产品的高级分销商港湾网络是年正式成立。饶有意味的是,就在李离开之际,任正非在五洲宾馆举办隆重的欢送会,期望港湾成为华为内部创业的典范。2001年,港湾推出路由器和交换机等产品,港湾与华为自此反目,任正非昔日的爱将,在此后7年的时间内,不断跟这位华为“老船长”开着不合时宜的玩笑。

  “李一男在离开华为后的4年内,并没有与华为直接竞争。这其中除了种种说不清的竞争利益之外,还能看到李本人对任正非、对自己在华为的5年经历的认同与尊重。”熟悉港湾的一位资深评论人士认为,“2005年9月是港湾与华为正面冲突的分水岭,2005年是华为国际化拓展历史上最为重要的一年,华为先后与沃达丰和Telefónica签署战略合作协议,共同开发以欧洲和拉美为主的全球市场。面对竞争对手西门子欲收购港湾的消息,华为向港湾发出律师函,要求港湾尽快解释对华为多项产品的知识产权侵犯问题。”

  2005年11月西门子移动网络部门总裁克里斯托弗·卡塞里茨公开表示,将在中国开展一次15个收购项目的大胆计划,这使外界更加相信港湾是西门子最佳收购目标。2006年西门子基于华为与港湾的知识产权纠纷问题,宣布放弃收购港湾。从此,港湾不断传出被某公司收购的传闻,直至港湾成为华为囊中之物。

谁能让李一男走人

  2006年6月,华为宣布收购港湾网络——没有新闻发布会,没有红酒,李与任正非这对昔日的师徒、如今的对手再次握手。

  “公司在发展中遇到很多困难和挫折,由于管理层,尤其是我本人在知识和能力方面的欠缺,导致在公司战略的制定和内部的管理上都存在很多不足,错失了企业发展的机遇,辜负了大家对我的期望,对此也感到深深的自责。”倔强的李一男从未作过像6月6日发给员工的内部邮件中那样诚恳的道歉。作为与任正非多年是非恩怨感情交错的后辈,5年前还接受任正非干杯祝愿的通信少帅,被迫放弃了自己一手养大的孩子。

  少帅李一男温顺回归华为,在许多接近李一男的人眼里是一件不可思议的事情。原港湾市场部公关专员杨先生在与记者聊天的过程中表示,8年前李一男的离职就已经注定了与老东家华为今后的关系将非常微妙。“李总跟着港湾回到华为让公司上上下下都感觉很惊讶,李总不像是屈服在资本意志下的人。”他说。

  据他回忆,华为收购港湾时,李本人的状态并没有因被迫放弃自己一手带大的“孩子”而失常。“相反,他看起来心情还蛮好,尽管公司上上下下的气氛都很不友好。”

  在李的价值观中,倔强与骄傲似乎从未走远,即使在与华为抗争中明显处于劣势,李一男也从未张口向昔日的故人作任何讨价还价。李的傲骨,与之前在华为颇为不利的人际关系,注定其在华为将再次度过孤寂的两年。

  李一男在华为与港湾的近10年中,一直都是一个备受争议的人物。他曾经用自己极其敏锐的技术嗅觉领导了华为的技术研发,也曾在后来与老东家进行的收购大战中处处被动。在两次进出华为的过程中,李一男收获了人生历程中最宝贵的经验、资本和为人处世之道,却失掉了与生俱来骄傲的天性。

  与李一样,华为副总裁郑宝用也是任正非的得力干将。他先后主持华为公司几代交换机的设计与开发。任正非提倡副总裁每周和客户面谈几次的制度,郑宝用完成得最好,任正非为此经常夸奖他进步快。

  对于李和郑,任正非并没有像柳传志那样协调好二虎相争的关系。树欲静而风不止。尽管两个当事人相互之间并没有成见,但公司内部人言可畏,许多人都风传两人争夺任正非接班人的位置,这一度让社会关系学不佳的李一男非常被动。

  如今,大多数华为内部员工都认为,李一男此次离开华为加盟百度,原因有二:其一是有了李一男第一次“叛逃”华为的经历,任正非对其信任已经大打折扣,此后的两年时间内,李本人一度以首席科学家的职务被华为雪藏,没有施展身手的机会;其二是李本人的倔强使自己在华为内部并不受欢迎。

  华为的同行、四川迈普集团品牌推广部经理刘炜知道李一男离开华为后,用了易卜生《玩偶之家》式的“出走”二字来形容李的离职。他认为,任何人都明白李一男的技术天赋对华为的意义,但李根本得不到重用,所以李的离职“应该只是时间问题”。

  伟大的领导者都是“一个人的表演”,但其中真正伟大的却是那些在表演之余仍能将政治和人际关系把控于掌中的人。与华为的第一次反目经历毫不意外地注定李一男在今后的两年内不会再得到任正非重用,叛逆而倔强的个性也因此失去了最有力的支撑。36岁时,李一男只能郁闷地说:“我们没有别人幸运。”而38岁时,他必须选择离开。

  山的那一边

  从华为跳槽到百度,从通信转行到互联网,淡出公众视野两年之久的李一男,再次回到公众的视野。通信少帅李一男加盟百度的消息传出后,业界震撼之余,对李一男和百度双方的选择充满猜想。

  与事件本身造成的影响相比,李本人保持了学术派沉稳低调的风格,或许是考虑到此次转型的轰动程度之大。记者第一时间致电百度市场部,对方表示,李一男在加盟百度的前三个月将潜心熟悉业务,不接受任何采访。

  对于李选择百度,业内很多人不理解这一行为,不知道百度如何为李一男提供足够的发展空间,也不理解李一男如何通过百度这个平台来发挥他的“天才”价值。对此,华为内部知情人士认为,李一男选择离开华为并加入百度是非常合适的选择。对于他来说,经历了港湾的失败以后,没有必要贸然重新再次创业。他选择了百度以后,应该不会轻易回到通信行业,因为互联网有着更大的发展空间。

  “李一男的眼光非常敏锐,他的事业选择即表示了他对未来的选择。而这种选择往往具有极强的前瞻性。”这位高层告诉记者,“由于有通信行业的深厚积累,李一男进入与通信关联紧密的互联网行业障碍不大。通信行业独特的视角为李一男提供了转型的资本,而百度正好提供了这种实践机会。”

 
 

alpha混合

Dst.Red    = Src.Red   * alpha + (1-alpha) * Dst.Red  ;

Dst.Green  = Src.Green * alpha + (1-alpha) * Dst.Green;

Dst.Blue   = Src.Blue  * alpha + (1-alpha) * Dst.Blue ;

Dst.Alpha  = Src.Alpha * alpha + (1-alpha) * Dst.Alpha;

10月20日

千橡收购kaixin.com域名 校内许朝军:使用有待规划

  CNET科技资讯网 10月10日 北京消息:记者今天从千橡互动集团(下称“千橡”)证实,千橡已经收购kaixin.com域名,该域名的“所有权”昨天正式转到千橡名下。

  收购价格十几万美元

  众所周知,开心网与千橡旗下校内网是直接竞争对手,而近来开心网风头正盛,媒体蜂拥报道,就连《时尚》10月刊上,也见到以“开心网”为选题的文章。千橡收购此域名,意图似乎很明显。

  校内网许朝军在接受CNET记者采访时表示:“该域名昨日才转过来,我们还没计划怎么去用。”而至于收购该域名的价格以及收购的目的则统统保密。

  但据域名信息交流平台尊米网的王权锋透露,“千橡应该在6月底或7月初的时候与kaixin.com的所有者接触,因为我在7月12日的时候也与美国方面商议收购该域名的事宜,但对方称在半月前已经有他人与其接触,并达成初步共识。”

  价格方面,王权锋猜测在十几万美元,“因为今年线下收购成交价最高的就是我7月十几万美元收购的e*in.com,美国没有传出更高的收购记录。”

  该域名会否指向校内网?

  许朝军说还未计划如何使用该域名。这句话或许可以理解为在当下敏感期对记者的官方答复。更多业内认为,千橡收购了竞争对手开心网的域名——kaixin.com,很可能将该域名指向自己旗下的SNS网站校内网。

  由于开心网目前拥有较高的品牌知名度,校内网通过将kaixin.com这个域名SEO(搜索优化)后,在扩大自己品牌影响力的同时,对开心网也将产生极大的打击。

  实际上,早前也有类似的案例,比如曾经著名的分类网站“zhantai.com”因某种原因关闭后,58.com注册了“zhantaiwang.com”,现今“站台网”上全是58.com提供的链接,对站台网原来的用户造成误导。

  另外,IT电子商务网站“京东商城”也针对其竞争对手的域名做了搜索优化。搜索“易迅”、“新蛋”这两家电子商务网站,搜索结果第一条是京东商城,并伴有广告语:现在都去京东网购了。

  毫无疑问,此举大大提升了自己的品牌知晓度,同时给对手造成了不利影响。

  开心网的失误?

  kaixin.com可以说是最适合开心网应用的全拼域名,早在几个月前就成为众多业内公司热门求购的目标域名。最后被国内网络公司9158.com成功购得。7月31日,域名kaixin.com的whois信息显示注册者为浙江杭州的“mike fu tengtao@9158.com”。此后在昨天转到千橡名下。

  在此过程中,本该扮演主角的开心网为何未能购得此域名?

  据知情人士透露,开心网在9158.com成功收购前,一点动作都没有。只在9158.com收购之后才有想到去买此域名,但实际上,本身kaixin.com这个域名是千橡委托9158.com这个公司去收购的。该人士感叹:“开心网又如何能从千橡手中再买回来?”

  有业内人士认为,这根本不是开心网的一次失误,该事件反映的是开心网没有这个意识。“做技术的人对市场总是抱着无所谓的态度。开心网的初创员工就是一群工程师。”

【作者:张丹 来源:CNET中国】 (责任编辑:孙立彬)

Kaixin.com回国 开心网是否改名不得而知

2008-07-31 09:14:16 来源:中国站长站 作者:编辑整理 【 评论:6

据网友爆料,开心网 www.kaixin001.com 没有正式发布,kaixin.com竟然被9185.com的人拿到手了。现在kaixin.com 仍然处于停靠parking 状态

下面是kaixin.com今天的Whois信息:

Domain Name: KAIXIN.COM

Registrant [1460322]:

mike fu tengtao@9158.com

9158.com和kaixin001.com同样是在做运营社交网站,这两家网站的业务上明显存在的竞争关系。关系有点像当年的made-in-china.com和hc360.com具有明显的行业相似性,两家如果出现像madeinchina.com一样域名品牌事件。处在内测中的kaixin001.com明显将会为9158.com做嫁衣,精心打造的开心网品牌因kaixin.com域名策略将眼睁睁的为别人带流量。

9158.com是四数字病毒米,从更深层次来讲如果要建立新的品牌更换新的域名也并不是不可能的。kaixin001.com在9158.com结尾的新主人手中,其背后的含义也许不仅仅是友情帮忙,即使kaixin.com回国只是在9158.com中转,从竞争关系的那边二转手域名,也有可能有更深层的人事、品牌或资本上的变动。

kaixin.com已经到了9158.com结尾的新主人手中。9158.com和kaixin001.com如果没有什么深度的合作的话,那kaixin001.com正式发布后估计要改名字了。

hainei.com和开心kaixin001.com同属于一个类型的域名,开心网是否有意在正式上线后改为启用新域名目前还不得而知。

kaixin001.com做为在IT圈子里快递发展起来的网站,前期对域名品牌的不重视,造成了今天的这种尴尬局面。开心网对kaixin.com的域名品牌回国的对策目前尚不得而知。

10月19日

实在佩服百度的服务取名

聊天工具,大概是聊天第一句常常是Hi,所以聊天工具叫做"Hi";
C2C,大概是买卖的第一句对话是"有没有某某商品?回答有啊",所以,C2C叫做"有啊";
 
10月16日

不惮以最坏的恶意来推测中国人

2007,我的工作是单片机开发/驱动程序开发,大多的开发工作都是用汇编语言,同时,由于需要和国内业务往来的公司沟通,安装了腾讯QQ,我本身是MSN Messager的铁杆fans.也许是工作的关系,在托盘显示一个QQ图标觉得不太好,所以写了一个小工具,用于自动伪装托盘,同时也去掉了大部分广告.
很偶然的机会,和一个盲人朋友,网名"晴天"交流,把这个粗糙的不能再粗糙的工具发给了对方,由于LiteIM的一些功能很细致,居然在他的朋友圈中很受欢迎.时不时的增加功能,也就成了最后的fineplus.
做LiteIM系列的开发,纯粹是出于自己使用的需求,以及对调式的兴趣.也许你喜欢吃某食物,偶然会饶有兴致的自己做一次,或几次,但是很难长时间去做,因为那毕竟不是工作.所以,很自然的,兴趣总有消褪的时候,这结果,就是跑去餐馆吃,而不再自己煞费心思的做,开发也是同理.当然,除了兴趣消失,还有法律方面的压力.既然没什么兴趣,又有法律问题,那么何必继续呢?没有任何必要继续了.
fineplus 在1.43.5后基本上没有更新,后续的1.45仅仅是适应性调整,同时也默认不再去掉任何广告,也算是较好的脱身吧.
 
至于彩虹,在fp停止跟新前几个月就已经出现了,发现彩虹团队的这个作品时,我们同样也是很纳闷.当然,他们的产品定位,市场推广策略肯定有其理由.
 
对于网络里面出现的一些外挂,一方面堂皇冠冕的反对打包,另一方面却像联盟似的到处找人合作,这种做法有些让人不齿.很多次在完美论坛发现作者自己跑来泄露测试版.我们看不惯这些做法,对于该外挂,以及所谓的双显,修改版等,一律删除,当然,没有太多时间来一个一个看主题,我们的做法是不定期的在后台删除所有满足特定关键字的主题.
 
fineplus,如果您曾因为它得到过便利,请不要在它离开时诋毁.
 
10月4日

集成补丁到VS安装包

1.解压缩安装源(2005及其以后的版本使用cab压缩存放,需要先执行这一步,执行完后把根目录下的其他文件拷贝到新目录,不可覆盖新目录中已有的文件,cab文件不必复制;VS2003不需要此步骤,直接拷贝一个目录备用即可)
msiexec.exe /a D:\Downloads\VS2003\VS2003EN\vs_setup.msi TARGETDIR=D:\Downloads\VS2003\VS2003ENSP1\ /L*vx install.log
2.把msp文件从补丁的exe中释放出来
VS7.1sp1-KB918007-X86.exe /Xp:VS7.1sp1-KB918007-X86.msp
2.应用补丁
msiexec.exe /a D:\Downloads\VS2003\VS2003ENSP1\vs_setup.msi /p "D:\Downloads\VS2003\VS7.1sp1-KB918007-X86.msp" /L*vx patch.log

winrar压缩时排除特定目录

压缩svn版本控制下的文件时,目录中总是有很多.svn目录,如何在压缩时自动排除它们呢?
 
在 排除文件中加入 *\.svn *\.svn\* 即可
10月3日

Visual C++ .NET Standard Edition - Free Optimizing Compiler

 
Tuesday, June 29, 2004
By: Jason Doucette
Printer Friendly Version

February 24, 2007 Update: Visual Studio .NET 2003 Service Pack 1 has been released.  Since this fixes Visual C++ 2003 Standard compiler bugs, it begs the question:  Should I: A. Upgrade Visual C++ 2003 Standard to SP1, and use the newly fixed non-optimizing compiler?  B. Not upgrade to SP1, and continue using the optimizing compiler of Visual C++ Toolkit 2003?  C. Upgrade to Visual C++ 2005 Express Edition, which contains an "enhanced version of the C/C++ optimizing compiler", which obsoletes all Visual C++ 2003 versions, except that it does not include ATL or MFC?  D. Possibly trick the SP1 installer into upgrading the Visual C++ Toolkit 2003's optimizing compiler?  Please follow / join the discussion on our forums.

May 18, 2006 Update: The Visual C++ Toolkit 2003 has been replaced with Visual C++ 2005 Express Edition, which is also free.  This page states, "Visual C++ 2005 Express Edition also contains an enhanced version of the C/C++ optimizing compiler for the fastest executables."  This makes Visual C++ 2003 Standard and Visual C++ Toolkit 2003 obsolete, except that Visual C++ 2005 Express does not include ATL or MFC.  Also, since it not desirable to upgrade Visual Studio during mid-project, you may still want the Visual C++ Toolkit 2003.  Thus, we have it available for download from Xona.com:

Download: Visual C++ Toolkit 2003 (v1.01) released July 6, 2004 (29.9 MB)

 

Anyone who has purchased Microsoft Visual C++ .NET Standard Edition (version 2002 or 2003, a.k.a. version 7.0 or 7.1, and VC7), which is much cheaper (estimated retail price: $109 USD) than the entire Microsoft Visual Studio .NET Professional Edition package (estimated retail price: $799 USD), has been annoyed that it does not come with the optimizing compiler.  You need not worry anymore.  Microsoft has released the Visual C++ Toolkit 2003 for free, which includes "the same compiler and linker that ship with Visual Studio .NET 2003 Professional!"

 

How do I instruct Visual C++ .NET Standard to use the Optimizing Compiler?

Download and install the Visual C++ Toolkit 2003.  Take a look in the 'bin' directory from its install location:
C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin

You should see five files that start with 'c'; they are the compiler files:

  1. c1.dll
  2. c1xx.dll
  3. c2.dll
  4. cl.exe
  5. cl.exe.config

These are the files you want the GUI to use now, instead of the versions it is currently using.  Take a look in the 'bin' directory of your Visual C++ .NET Standard Edition install location:
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin

You should see these same five files.  These are the files the GUI is currently using.  There are two ways to instruct the GUI to use the files from the Toolkit:

  1. Method One (preferred):
    Go into Tools -> Options... -> Projects folder -> VC++ Directories.  Under 'Show directories for:', select 'Executable files'.  Insert the Visual C++ Toolkit's bin directory (C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin) at the top, so these files are found first and used, when the GUI starts looking for them.

  2. Method Two:
    Make a backup copy of the Visual C++ .NET Standard Edition files, and then overwrite them with the Visual C++ Toolkit files.  The next time you compile, you will be using the optimizing compiler.  I should note that on Brian Johnson's article regarding the Toolkit, Pheo stated that it was not necessary to overwrite the c1*.* files.  I have found overwriting them has causes no problems.  If they ever do, you can restore the originals from the backup copies.

 

The .NET Standard GUI still grays out the Optimizing Switches.

You are going to find that Visual C++ .NET Standard's GUI is still going to have the optimizing compiler switches grayed out:

This is not a problem thanks to the 'Command Line' option under the 'C/C++' folder within this same window.  Simply look up the compiler options, and add them here.  Be sure that you add these to your release build, not your debug build.  If you were to try this with the original non-optimizing compiler, it will complain about the unsupported switches.  If it does not complain, then you are successfully using the optimizing compiler.

 

Purchase the much cheaper Visual C++ .NET Standard Edition

There is now little reason to spend eight times the price for Visual Studio .NET Professional, when the optimizing compiler is freely available, and can be installed easily using my explanation above.


Microsoft Visual C++ .NET
Standard Edition 2003

 

Which Additional Switches do you Recommend?

Firstly, there are many optimization switches that are available via the GUI within Visual C++ .NET Standard Edition, such as /G7 (Optimize for Processor), which optimizes the code for the Pentium 4 and Athlon processors, but still creates an executable backwards compatible with older processors.  I would recommend that you look through and see what you can change without requiring the manual addition of parameters to the command line.  Once you have done this, I recommend the following for the command line:

  • /O2 - Maximize Speed: This switch is identical to using the following switches: /Og, /Oi, /Ot, /Oy, /Ob2, /Gs, /GF, and /Gy.  This is set by default in the Professional Edition for release builds. 
  • /arch - Minimum CPU Architecture: Use this if you know for certain the application will only be run on systems that minimally support Streaming SIMD Extensions (SSE) or Streaming SIMD Extensions 2 (SSE2).  Note that the resultant executable will not run on a CPU that does not minimally support the instruction set you specify.

For further reading, the following two articles will give you some additional information on optimization switches, and what they accomplish:

  1. Optimizing Your Code with Visual C++
  2. Visual C++ Optimization Overview

 

Problems and Recommendations

In the Project -> Properties, under Configuration Properties -> General, there is a switch that is already enabled from the Standard Edition GUI called 'Whole Program Optimization'.  It defaults to 'No', and the explanation text does not indicate any compiler switch that this selection may represent.  I would assume that this represents the /GL (Whole Program Optimization) switch.  If you set the selection to 'Yes' and compile, you will notice in the build log that the GUI does not pass the /GL parameter to the compiler.  If you want this switch (it is recommended for release builds), then you must add it manually to the command line parameters.  In general, it is beneficial to look up each compiler switch to understand its effects, and it may be easier for some people to merely add them all to the command line manually.

 

Minimizing Code Size

When code size is a concern, you should use the /O1 (Minimize Size) switch (which is identical to using the following switches: /Og, /Os, /Oy, /Ob2, /Gs, /GF, and /Gy).  For multithreaded applications, the most effective way to reduce the size of the resultant executable is to use the /MD (Use Run-Time Library) switch which creates a multithreaded, dynamic linking executable file using MSVCRT.LIB (which requires the existence of MSVCP71.DLL to run), as opposed to using the regular /MT (Use Run-Time Library) switch which creates a multithreaded, static linking executable file using LIBCMT.LIB.  For an example of the decrease in executable size, my current project was reduced from 216 Kb to 144 Kb when I switched from /MD to /MT.

Please note that an application that is dependent on MSVCP71.DLL must redistribute it in the directory containing the executable.  When you do this, the size of both the executable and the .dll file are likely larger than if you just used the regular /MT (Use Run-Time Library) switch.  However, in the case of Visual C++ 6.0 users, the run-time library is installed by default on Windows 98 / Windows NT and above, so the .dll distribution is not required.

 

Visual C++ 6.0 Users

On a recent K-v-R thread,  'texture' and Stefan Kuhn mentioned a way to incorporate the optimizing compiler in Visual C++ 6.0 Standard Edition.  The method to accomplish this is similar to the first method explained above (the addition of directory paths), except for one thing.  The optimizing compiler needs access to its own lib and include folders (in addition to the bin directory) that were create during the install of the Visual C++ Toolkit 2003.  Therefore, you need to add all three of these following directories to the appropriate directory lists:
C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin
C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib
C:\Program Files\Microsoft Visual C++ Toolkit 2003\include

You can make the compiler aware of these folders by adding them to the top of the directory lists, so they are searched first.  Do this by going into Tools -> Options -> Directories tab.  Note that you will need to make a different selection under 'Show directories for:' each time you add a path.  Add the bin directory to the 'Executable files', add the lib directory to the 'Library files', and add the include directory to the 'Include files'.  You must ensure that you make these paths the first path in the list, so when the GUI seeks out its required files, it will find the files in these directories first, instead of the original files in the original locations.

 

Visual C++ 6.0 Problems

I advise you to read the K-v-R thread mentioned from this point onward, as it mentions numerous potential difficulties you may run into.  There is also a thread on GameDev.net that you may like to read.  I will summarize a few problems below, but I cannot guarantee that your programs will compile even if you take heed the points I mention.  The best you can expect is that they will compile, but you will still lose the use of your debugger.  Ihighly recommend upgrading to the cheap version of  Microsoft Visual C++ .NET 2003 (VC7) Standard Edition, as you will have no problems installing and using the optimizing compiler with it.

Stefan Kuhn has pointed out that if your program links to the multithreaded DLL run-time library (MSVCRT.LIB), there will be linking errors.  Specifically, for any double to long conversions, the optimizing compiler will generate code that references the _ftol2 function.  The linker will fail with the error: "unresolved external symbol __ftol2" (the extra underscore in the error report is due to "name mangling"; the compiler adds an underscore to exported / external function names).  The solution is to link to the static C run-time library, instead of the multithreaded DLL run-time library.  For multithreaded applications, this is LIBCMTD.LIB for debug mode, and LIBCMT.LIB for release mode (the multithreaded versions of LIBCD.LIB and LIBC.LIB, respectively).  Ensure that you are linking to the static C run-time libraries for both debug and release builds.

When you compile for debug mode, calls to run-time checks will be inserted that reference functions beginning with __RTC.  The linker will fail to link these functions if you are linking with the multithreaded DLL run-time library (MSVCRTD.LIB) or the multithreaded static C run-time library (LIBCMTD.LIB).

If your program is targeted for Windows ME or above (when WINVER has been set to 0x0500 or higher), you should not have these problems.  However, if your program is targeted for Windows 98 or earlier (when WINVER has been set to a value below 0x0500), the functions mentioned will not be implemented in certain run-time libraries, and the linker will complain if you attempt to use them.

 

By: Jason Doucette
(Interested in Writing Articles For Xona.com?)