??xml version="1.0" encoding="utf-8" standalone="yes"?>
对COM接口?qing)其使用的数据类型来_(d)是否采用l一的链接规范,对其二进制兼Ҏ(gu)和可移植性都没有影响。因接规范主要媄响到名字改编Ҏ(gu)的不同,q样即接口两端Ҏ(gu)口本w的解释不通,只要它们使用一致的成员寚w方式和布局Ҏ(gu)、一致的函数调用规范、一致virtual function实现方式QL是一致的C++对象模型。ƈ且保证COMlg升时不改变原来的接口和数据cd定义Q则所有方法的q行时绑定都不会(x)存在问题Q所有方法的调试都被转换为通过对象指针对vptr和vtable?qing)函数指针的操作Q这U间接性不再需要Q何方法名卛_数名的参与,而接口名和方法名只是Z让客L(fng)的代码能够顺利通过~译Q但是连接时完全不在需要了。)
但是对于定义于普通静态链接库和动态链接库中的全局数据cd、全局函数、全局变量甚至全局帔RQ它们的q接规范必须在两端保持一致、否则客L(fng)序会(x)出现q接问题。这是因为普通的装为DLL的函数库或者类库,客户E序在创Z一般都需要与它们的导出库q行q接Q除非用loadlibrary()和getprocaddress()函数Ҏ(gu)获得DLL中函数的地址Q通用的连接规范要属Cq接规范Qextern‘C’?/span>
具体使用Ҏ(gu)Q?/span>里仁教育嵌入式培?/span>职业讲师详情讲解Q?/span>
Extern’C’void WinMainCRTStartup()Q?/span>
Extern’C’const CLSID CLSID_DataConvert()Q?/span>
Extern’C’struct Student{.......}Q?/span>
Extern’C’student g_student;
如果是对一D代码指定连接规范:(x)
#ifdef _cplusplus
Extern ‘C’{
#endif
Const int MAX_AGE=200Q?/span>
#pragma pack(push,4)
Typedef struct _person
{
Char *m_Name;
Int m_Age;
}person,*personPtr;
#pragma pack(pop)
Person g_Me;
Int _cdecl memcmp(const void*,const void*,size_t)Q?/span>
Void * _cdecl memcpy(void,const void*,size_t)Q?/span>
Void* _cdecl memset(void*,int,size_t)Q?/span>
#ifdef _cplusplus
}
#endif
l 使用Kill命o(h)来消灭进E?/span>
如果q行了某个程序导致了LQ那么就应该切换到其他的控制CQ按下ctrl+alt+fxQ其中x可以?·5Q这取决于用L(fng)try的多?/span>
用ps昄q个E序的进EID?/span>
q里以xchatZ?/span>
$ps aux |grep xchat
Wanglin 12063 0.0 1.8 89536 19028 ?S1 apr06 2:40 xchat
其中12063是它的ID?/span>
也可以用pgrep来显CIDQ如下:(x)
$pgrep xchar
12063
使用Kill来消灭这个进E?/span>
使用kil来消灭进E,如果消灭不掉Q还要加参数-9Q它可以强制l束q程?/span>
$ kill 12063
$ kill -9 12063
l 使用pkill或者killall来消灭进E?/span>
它们的共同点是都可以用E序的名UC为参数?/span>
$ pkill -9 xchat
$ killall xchat
l 使用囑Ş化的方式来消灭进E?/span>
$xkill
?x)出C个X形的光标Q单击需要消灭的H口Q就可以消灭q个E序?a >www.lirenedu.org
1. 命o(h)格式
#patch -p1<[patchfile]
或?/span>
#patch -R <[patchfile]
上面两个格式任选一条就可以了?/span>
2.使用Ҏ(gu)
#patch -p1<[patchfile]
要求补丁文g要放到源代码目录下,然后在运行这条命令?/span>
例如Q给xchat2.6.0打补丁, 补丁文g是xc260-fetext.diff?/span>
首先选入 xchat2.6.0的目录, q且xc260-fix-fetext.diff文g复制到这个目录,然后q行Q?/span>
#patch -p1<xc260-fix-fetext.diff
如果出现提示信息Qpatching file src/text/fe-text/fe-text.c q说明打补丁成功了?/span>
#patch -R<[pathfile]
q个命o(h)q行后,q要指定被补丁的文g的\径和文g?www.lirenedu.org
临时改变|络参数
l .Ifconfig:查看和配|IP地址?/span>
$ifconfig eth0
$sudo ifconfig eth0 192.168.9.23 netmask 255.255.255.0
route:配置路由参数
$sudo route add default gw 192.168.9.1 eth0 #讄默认|关
使参数立即生?/span>
$sudo/etc/init.d/networking restart
修改|络配置文g
讄DNS服务器?/span>
$sudo echo‘nameserver=219.150.32.132>/etc/resolv.conf’
~辑/etc/network/interfaces?/span>
$sudo vim /etc/network/interfaces
Auto lo
Iface lo inet loopback
Iface eth0 inet static #讄eth0,静态IP
Address 192.168.8.45
Netmask 255.255.255.0
Gateway 192.168.8.1
Iface eht1inet dhcp #讄eth1为dhcp模式
l 可以通过下面的命令设|\由?/span>
Up route add default gw 192.168.8.1 eth1
Up route add –net 192.168.8.0/24 gw 192.168.8.1 eth0
Down route del –net 192.168.8.0/24 gw 192.168.8.1 eth0
其中Q当|络接口upӞ执行它后面的命o(h)Q当|络接口downӞ执行它后面的命o(h)?/span>
使用参数立即生效?/span>
$sudo /etc/init.d/networking restart 转:(x)www.lirenedu.org
1. pȝ信息
l 查看内核信息?/span> $uname -a
l 查看操作pȝ的版本?/span> $head –n 1/etc/issue
l 查看CPU的信息?/span> $cat /proc/cpuinfo
l 查看计算机名U?/span> $hostname
l 列出所?/span>PCI讑֤信息?/span> $lspci –tv
l 列出所?/span>USB讑֤信息?/span> $lsusb –tv
l 列出pȝ加蝲的模块信息?/span> $lsmod
2. pȝ资源的用信息?/span>
l 查看内存和交换区分的使用量?/span> $free –m
l 查看盘分区的用情c?/span> $df –h
l 查看某个目录的大?/span> $du –sh<目录>
l 查看内存总量和空闲内存量?/span>
$grep memTotal /proc/meminfo
$grep memfree /proc/meminfo
l 查看pȝq行旉、用h和负载?/span>$uptime
l 查看pȝ负蝲?/span>$cat /proc/loadavg www.lirenedu.org
~译器无法预期一个程序在执行q程中会(x)在何时创Z些什么对象,而只能根据当时的上下文要求创建,对象的初始化最好能够通过q行时执行一个函数来完成Q而且是在对象创徏的同Ӟq个函数是构造函敎ͼ同样Q对象在完成其命的时候能够通过一个函数来销毁,q就是析构函数?/span>
当给一个对象分配好原始内存I间的时候,q个对象应该算创徏h了。只不过它还处于一U?#8220;原始状?#8221;Q即末初始化的,不良的状态,如果把这L(fng)内存直接拿来使用Q除非第一个操作是赋|否则极有可能出错。例如:(x)
Long long1; //局部变?/span>
Count<
Char*pstr=(char*)malloc(1024);
Cout<
因此Q创Z个变量或动态对象时一定不要忘记初始化?nbsp;初始化就是在对象创徏的同时用初值直接填充对象的内存单元Q因此,不会(x)有数据类型{换等中间q程Q也׃?x)生?f)时对象,而赋值则是在对象创徏好后M时候都可以调用的而且可以多次调用的函敎ͼ׃它调用的?#8220;=”q算W,因此可能需要进行类型{换,即会(x)产生临时对象?/span>
C++对象可以使用构造函数来初始化,构造函数是M对象创徏时自动调用的W一个成员函敎ͼ也是为每个对象仅调用一ơ的成员函数Q所以构造函数的作用是Q?/span>当对象的内存分配好后把它原始状态变成良好的可用的状态?/span>
有的E序员可能认为:(x)虽然我没有在构造函C初始化数据成员,但是我在声明一个对象后马上调用它的set-XXX()函数来初始化它的每一个成员,效果也是一L(fng)?/span>
最好ؓ(f)每个cL式地定义构造函数和析构函数Q即使它们暂时空着Q尤其是当类含有指针成员或引用成员的时候?/span>
构造函数的另一重要用途就是给一些可能可能存在的隐含成员如vptr创造一个初始化的机?x),否则虚拟机将不能保证实现Q每当此Ӟ如果E序员没有ؓ(f)一个多态类昑ּ地定义默认构造函数、拷贝构造函数、析构函数或拯赋值函敎ͼ那么~译器会(x)自动得生成相应的函数Q它们都是public inline的,q在其中插入正确初始化或修改vptr数据成员值的代码Q而且保基类对象和派生类对象构造时?qing)在它们之间拯时vptr能够指向或重新指向恰当的vtableQ这L(fng)4个函数分布叫非^凡默认构造函数、非q_拯构造函数、非q_析构函数和非q_拯赋值函数?a >www.lirenedu.org
1) _cedcl:q是C++/C函数的默认调用规?/span>Q参C叛_左传递压入堆栈,p用函数复杂堆栈的清退Q因此这U方式利于传递个数可变的参数l被调用函数。如printf()是q样的函数?/span>
2) _stdcall:q是Win API函数使用的调用规范,参数从右向左依次传递ƈ压入堆栈Q由被调用函数复杂堆栈的清退。该规范生成的函C码比_cdecl更小Q但当函数有可变个数的参数时?x){为_cdecl规范。在Windows中,宏WINAPI、CALLBACK都定义ؓ(f)_stdcall?/span>
3) _thiscall:是C++非静态成员函数的默认调用规范Q不能用个数可变的参数。当调用非静态成员函数的时候,this指针直接保存在ECX寄存器中而压入函数堆栈,其他斚w与_stdcall相同?/span>
4) _fastcall:该规范所修饰的函数的实参被直接传递到CPU寄存器中而不是内存堆栈中Q堆栈清退p调用函数负责Q该规范不能用于成员函数?/span>
函数必须制定的一个调用规范,特别是在模块之间的逻辑接口中,每个函数原型的调用规范必M其实的调用规范保持一_(d)否则?x)出现编译连接错误。如果你调用了在某个DLL中实现的COM对象的方法,而这些方法在创徏时却没显式地制定调用规范Q那么它们会(x)使用环境默认的调用规范,虽然你的E序可以通过~译和连接,但是在运行时可能导致程序崩溃?/span>
所以,凡是接口函数都必L式地制定其调用规范,除非接口函数是类的非静态成员函敎ͼ如果不显式制定调用规范,cȝ静态成员函数和全局函数采用C++/C默认的函数调用规范或者由工程讄指定的调用规范,因此最好也为静态成员函数显式地指定调用规范?/span>
注意Q类的静态成员函数的默认调用规范不是thiscallQ类的友元函数的调用也不是thiscallQ它们都是由函数本n指定或者由工程讑֮的。COM接口的方法都指定_stdcall调用规范Q而我们自己开发COM对象?qing)接口时也可以指定其他的调用规范?/span>
一定要知道C基础的基本概念:(x)
认识函数堆栈Q?/span>http://www.lirenedu.org/index.php?ack=xinwen&id=1026
ZC语言基础概念Q?/span>http://www.lirenedu.org/index.php?ack=xinwen&id=1024
操作pȝ几个基本要点Q?/span>http://www.lirenedu.org/index.php?ack=xinwen&id=1029
二?/span>可拷贝构造和拯赋值的Q既hpublic?/span>copy constructor?/span>copy assignment operatorQ不论是~译器默认还?/span>operatorQ如果没有显式定义它的话Q这个条件可归结为:(x)元素必须是拷贝的Q但实际上拷贝赋值的要求也不是强制的Q原因和default constructorcM?/span>
三?/span>hpublic?/span>destructorQ不论是~译器默认的q是用户昑ּ定义的?/span>
四?/span>对于兌式容器,要求其元素必L可比较的?/span>
Auto_ptr满上述条g吗?臛_满前三条,因此臛_可以作ؓ(f)序列式容器的元素Q如果ؓ(f)auto-ptr定义了比较运符的话Q应该还可以把它作ؓ(f)兌式容器的元素?/span>
但是auto_ptr的特Ҏ(gu)接管和{UL有权Q而不是像原始指针那样可以׃n实值对象,?/span>auto_ptr在初始化时接实值对象和拥有权,而在拯时会(x)交出实值对象及(qing)其拥有权?/span>
因此Q?/span>auto_ptr对象和它的拷贝不?x)共享实值它的拷贝ƈ不相同,然而根?/span>STL容器D义的要求Q可拯构造意味着一个着把一个对象赋值给另一个同cd对象生两个相同的对象Q显Ӟauto_ptr不能满q一要求Q与上面l论矛盾Q那么问题出在哪里呢Q?/span>
在揭开auto_ptr的之前需要了?/span>copy constructor?/span>copy assignment operatorQ的几种合法形式QQ何一个类都允怸UŞ式的copy constructorQ?/span>
C(const C©)Q?/span>
CQ?/span>C©Q;
同样Q?/span>copy assignment operator允许cM的两UŞ式?/span>
C& operator=Q?/span>const C ©Q;
C& operator=Q?/span>C & copyQ;
实际上,׃copy assignment operator为普通的q算W重载成员函敎ͼ因此q可以定义下列Ş式赋值函敎ͼ
C&operator=Q?/span>C copyQ;
如果要防止用h一些不合适的对象攑օ容器中,p求对象的设计和是实现者用一些语a支持但不常用的特征,也就是说Q要能够在编译阶D就Lq种h潜在危险性的行ؓ(f)Q常用的Ҏ(gu)是q其违?/span>C++静态类型安全规则?/span>
比如我们常用的函?/span>fopen(),当打开文gp|是返?/span>NULLQ按照传l的错误处理Ҏ(gu)Q在调用Fopen()后立x查其q回|如果?/span>NULLp行错误处理,如果返?/span>NULL改ؓ(f)抛出异常OpenFailedQ那么我们就不用在调?/span>fopen()后马上检查返回|而是在调用函数内部或者更高层的调用者那里设|异常处理器来捕莯个异常,C++保证Q如果一个异常在抛出Ҏ(gu)有得到处理,那么它将一直抛向上层调用者,直至main()函数Q直到找C个类型匹配的异常处理器,否则调用terminate()l束E序?/span>
可以看出Q?/span>异常处理机制实际上是一U运行时通知机制?/span>
Class DevidedByZero{}Q?/span>
Double DevideQ?/span>double aQ?/span>double bQ?/span>
{
IfQ?/span>abs(b)
{
Throw DevidedByZero()Q?/span>//提前异常发生条件ƈ抛出自定义异?/span>
Return a/b; //q才是可能真正发出错误的地方
}
Void test()
{
Double x=100,y=20.5
Try{
Cout<
}
CatchQ?/span>DevidedByZero&Q?/span>{
Cerr<< “ Devided by zero!”<
}
}
1. 判断指针是否?/span>NULLQ如果是则立ȝreturn语句l止本函数。例如:(x)
Void Func(void)
{
A *a=new(nothrow) AQ?/span>
IfQ?/span>a==NULLQ?/span>returnQ?/span>
……
}
2. 判断指针是否?/span>NULLQ如果是则立ȝexit(1)l止整个E序的运行,例如Q?/span>
Void FuncQ?/span>voidQ?/span>
{
A *a=new(nothrow) AQ?/span>
IfQ?/span>a==NULLQ?/span>exit(1)Q?/span>
}
3. ?/span>new?/span>malloc()预设异常处理函数Q例如,Visual C++可以?/span>_set_new_hander函数?/span>new讄用户自定义异常处理函敎ͼ也可以让malloc()享用?/span>new相同的异常处理函数?/span>
4. 捕获new抛出的异常,q尝试从中恢复?/span>
上述(1)和(2Q两U方式用最普通。如果一个函数内有多处需要动态申请内存,那么方式(1)显得力不从心,应该用方式(2Q来处理。不q在C++中我们提倡用方?/span>(4)?/span>
有一个很重要的现象要告诉大家Q?/span>
对于32位以上的应用E序而言Q一般情况下使用malloc()?/span>new几乎不可能导?#8216;内存耗尽’。我?/span>windows98下用Visual C++~写了测试程序:(x)
q个E序无休地运行下去,Ҏ(gu)不会(x)l止Q因?/span>32位操作系l支?#8216;虚存’Q内存用完了Q自动用gI间替?/span>
Void mainQ)
{
Int *p=NULLQ?/span>
Unsigned int len=1024*1024Q?/span>
WhileQ?/span>1Q?/span>{
P=new(nothrow) int[len]Q?/span> //或?/span> malloc(sizeof(int)*len)Q?/span>
If(!p){
Len>>=1; //len~小一?/span>
IfQ?/span>len==0Q?/span>
Exit(1)Q?/span>
ContinueQ?/span>
}
Cout<<“AllocatedQ?#8221;<<“Q?/span>len*sizeof(int)Q?#8221;<<“bytes.”<<endlQ?/span>
}
}
可以得出一个结论:(x)
对于32位以上应用程序,内存耗尽错误处理E序几乎毫无用处Q但是必d调不加错误处理将DE序的质量很差,千万不可因小失大?/span>