Symbian系统开发教程2_第1页
Symbian系统开发教程2_第2页
Symbian系统开发教程2_第3页
Symbian系统开发教程2_第4页
Symbian系统开发教程2_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

作者:谢兴enigma19971@转载需注明出处Symbian系统已经提供了一套已经定义好的内置的数器无关的,应当使用下面symbian系统提供的数据类型,而不要使用原生数据类型(native无符号的整数。一般情况下,使用TInt和TUint就可以了,除非是在考虑代码优化或兼容性的时候,才会用到TInt8,TInt16这样的类型。TInt或TUint类型的整数。TInt64.在版本8.0之前,Symbian系统中不支持64位的算术运算,而是用两个32位的值来实现64位的整数,在8.0版本之后,TInt64和TUInt64才被定义为longlong类型,真正使用64位的内置数据类型。TReal32和TReal64(TR这两个数据类型相当于单精度和双精度的浮点数,由于浮点数的运算要比整一般应尽量避免使用浮点数的运算。分别对应窄或宽的字符(注:所谓窄字符通常ASCII码字符,而宽字符是指unicTAny*意为指向任意内容的指针,在这种意义上讲,TAny相当于void,TAny*相当于这时,不要将它改写为:TAnyhello(TAny);TBoolisLarger(TInta,{return(a>b)?ETrue:EFal}if(isLarger(4,3)==ETrue){...}//错误,编译不过。if(isLarger(4,3)){...}2.1Symbian系统中的命名习惯:在Symbian系统中编写代码时,应当遵守种样{voidSetAge(TIntaA}在symbian系统中存在几种不同类型的类(class不同类型的类,其特性也各不相同。有的在堆(heap)上创建,有的在栈(stack)上创建,特别的是,类的实例(instance)的易区分型别,Symbian系统使用了一个简单的命名规则:类名以大写字母开头(T,C,R悉这个类,但类的命名规则可以帮助他弄清你的意图------如何用安全的方式初始化、使用下面,我主要讨论不同型别的主要特性。T类的行为类似于C++中的内置类型,因此,它们以T作前缀(”T”代表”Type”)。象内置类型一样,它们没有析构方法(destructor这导致的结果是:T类不能包含具有析构方法的成员变量。所以,一般情况下,T类的成员变量只能是内置类型的数据或者是其它的T类用”关系,而不是“拥有”关系(也就是说,这个T类对象并不负责对成员的创建和销毁的工象可以在栈上创建,当程序流程退出函数或产生leave(一种代码异常)的时候,系统自动清除它。即使T类有一个析构方法,在发生异常(在Symbian系统中,异常被称为leave)时Symbian系统也不会调用它,因为leave没有模仿标准C++的抛出异常的做法。对象放入到清除栈(cleanupStack在发生异常的时候,清除栈(cleanupStack)会释放这个对象。{RDebug::Print(_L("iamastuden{RDebug::Print(_L("please,don'tkillme}voidSampleFunction()CBase有两个特点:首先,它有一个虚的析构方法,这样,可以通过CBase指针来删除它的子类。代码如下所示:please,don'tkillme!其次,CBase类和它的子类,重载了new操作符,这使得当它在堆上创建的时候,自动以您不必在构造方法中去做这件事情。但是,在栈上创建对象时,情况此,C类的对象一定要在堆上创建。在类的析构方法中调用delete来删除它;后一种情况要复杂一些,在调用任何有潜在的异常(leave)的代码之前,要把这个指针放到清除栈(cleanupstack)中,否则有可能发生内存有的。和C类不同,Symbian系统中不存在一个对应的RBase类,所以一个R类应当有一个构造方法Create()或Initialize()这样的方法,它们用来分配资源,设置句柄成员变量的值,并返回错误代码或是产生异常。R类通常也有对应的Close或Reset()类,用来释放资源,重置句方法(当然,该方法也可以是其它名字,但它经常被命名为Close或是有一个析构方法释放资源,这会引起资源的泄露。或局部变量存在的。只有少数情况下,在堆上创建。果一个R类是一个堆上的自动变量(相对于成员变量您一但要保证资源被释放,而且,变量本身也要被释放。.?)不定义)一个私有的构造方法和赋值操作。M是单词Mixin的首字母。Symbian系统不赞成多继承的做法,因为这个引入额外的复杂性,被用来定义回调接口或者是观察者(observer)类。M类也可以被其它类继承。下面我们给出两个例子。{virtualvoidEatL(){virtualvoidNameL()classCCat:publicCB{virtualvoidEatL(){};//从MAnimal,经过MDomesticAnimavirtualvoidNameL(){};//从MDomesticA//Otherfunctionsomi上面的例子演示了一个从CBase类和一个M类派生的具体类。而类MDomesticAnimal又是从MAnimal派生的。象接口一样,由于不能被实例化,M类只能有虚(virtual)函数,不派生的。在定义完类以后,然后可以用使用它。代码如下:然下面的代码却是错误的。当用M类的指针引用一个对象的时候,如果用delete删除这个指针,则这个M类必须提供一代码没有问题。{virtualvoidEatL()virtual~MAnimal();//增加一个虚的析构方法。在Symbian系统中,字符串被称为“描述符”(descriptor因为它们是自我描述的。在的长度和内存布局的信息。现在,让我们来深入了解描述符的设计思想。在Symbian系统中,描述符是相当让人迷惑的,因为它的种类繁多。不同种类的描也不同于C语言中的字符串。现在我们来讨论:什么是描述符?它们是如何工作的?在探讨这些不同的描述符之前,先让我们需要弄清楚一个基本的概念:什么是字符串数据的“宽度”?这个长度指的是单个字符是8bit的,还是16bit的宽度。在早期的版本中,字符的宽度都是8bit的,后来为了支持Unicode字符集,从第5版起,Symbian系统将16bit的字符作为标准。Symbian系统现在支持这两种字符长度的描述符,除了Copy()和Size()两个方法以外,这两种宽度的描述符的行为是完全一致的,这两个方法的使用,我们后面再介绍。另外,有一套中立的描述符类型,16bit的宽字符。对中立(neutral)的类统第5版以后,默认的情况下,它们表示宽度为16bit的字符串。它们之间的关系比较另外一个问题是:描述符和字面量(literal)的区别。所谓字面量是指在编码的时候就其中的"Helloworld"就是字面量。在Symbian系统中,对它们的处理是很不一样的,这点我们在后面再介绍。有了这样的一些认识,现在我们可以来看看有哪些描述符类型。在Symbian系统中描述符类型有两大种类:不可修改(non-modifiable)的描述符和可修改(modifiable)的描述符。Length()方法返回了描述符的长度,因为,每个描述符对象在内存中的布局都是同样的,用4个字节来表示它所包含的数据的长度(实际上,只用了32个bit中的28个bit,剩余的4bit以,Length方法没有被它的子类重写,它对所有子类都有效。但是,根据实现子类的方法的不同,子类访问数据的方式也不一样,Symbian系统不要求它的子类通过虚来实现自己的访问数据的方法。不用虚函数重写的原因是因为,虚函数会给每个被派生的描述符对象增加4节字的额外负担,c++用这4个字节来存放指向虚函数度的4个字节中,28bit用来表示长度,剩下的4bit用来表示描述符的类型。目前,symbian系统中有5种派生的描述符类型,4bit限制了描述符的种类最多只能有16种,但这已经足够了。子类可以通过调用基类TDesC的Ptr方法来访问描述符的数据,Ptr()方法检查这4个bit,的内存布局,并在Ptr方法中使用硬编码的方法。后面,为了表述上的方便,我们也把度和访问数据的方法,另外,它实现了所有的您想用来处理常量字符串的操作。所有的可修改的描述符都从TDes基类派生,而TDes本身又是从TDesC派生的。TDes有一个额外的成员变量用来存放为该描述符分配数据的最大长度。MaxLength()方法返回了这个最大的长度。像TDesC中的Length方法一样,MaxLength()方法也不被TDes的子类继承。TDes类提供了一系列的方法,用来对可修改字符串数据的操作,包括对字符串的方法和复制赋值的方法。这些方法都不负责分配内存,假如它们超过了描述符的数据长度,例如,用Append方法在某个字符串后面附加另一个字符串时,在调用该方法之前,您法使用了断言(assertion)来确保描述符的最大长度不会被超出。如果发生内存溢出,错误。存陷阱。或TDes类的实例。现在我们来看看描述符的派生类,您可以实例化和使用派生类的对象。正如前面所说,这个地方是比较让人迷惑的,因为描述符存在大量的派生类。前面,我们已经解释过为什么每个类会有三个不同的版本,例如:TDes8,TDes16局:指针描述符和缓存区描述符。不同之处在于,指针描述符持有一个指向字符串的指针,据,也就是说字符数据本身构成了描述符的一部分。总结:TDes是所有的可修改的描述符的基类,并且它自己也是从TDesC派生的。它有一个能返回最大的内存容量的方法和一系列的用来修改字符串数据的方法。3.3指针描述符(pointerdescr宽度,都可以分为三个版本,例如:窄字符版本TPtrC8,宽字窄版本TPtrC16和中立的版的,但有时候,它们也可以在堆上使用,例如:作为一个CBase派生类的成员变量的时候。在不可修改的描述符(TPtrC)中,指向数据的指针存放在长度的后面,因此,指针描述符的总长度为2个字(word在可修改的指针描述符中,它存放在最大长度的后面,因此,总长度为3个字。下图比较了TPtr和TPtrC内存布局.iLength(12)iMaxLengthiPtr·Helloworld!TPtrCiLen描述符中的数据是常量。所有的从基类TDesC中继承的操作都是可访问的。TPtrC定义了一系列的构造方法,使得它能从其它的描述符、指向内存的指针或以0结尾的C语言字符串构造。//字面量描述符将在后面介绍_LIT(KLiteralDes,"Sixtyzipperswerequicklypickedjutebag");TPtrCpangramPtr(KLiteralDes);//从TPtrCcopyPtr(pangramPtr);//从其//TText8isasingle(8-bit)character,equivconstTText8*cString=(TText8*)"Waltz,badnymph,forquickjigsTPtrC8anotherPtr(cTUint8*memoryLocation;//PointerintomemoryinitializedeTIntlength;//LengthofmemorytoberepresentedTPtrC8memPtr(memoryLocation,length);//从一个指针构造。这个指针本身可以改变成指向其他的字符串改变您的TPtrC所指向的数据,那么您可以将TPtrC声明为const,这样,当您试图用Set ()方法更改TPtrC所指向的数据时,编译器会产生警告。//字面量描述符_LIT(KLiteralDes1,"Sixtyzipperswerequicklypickedfromthewovenjutebag");_LIT(KLiteralDes2,"Waltz,badnymph,forquickjigsvex");alpha.Set(KLiteralDes2);//alphapointstothedatainKLibeta.Set(KLiteralDes1);//betapointstothedatainKLiteralDes1constTPtrCgamma(beta);//Pointstothedatainbeta,KLigamma.Set(alpha);//Generatesawarning,butpointsto针构造,并设置适当的长度值和最大长度值。Des()方法,这个方法返回一个如下所示的TPtr对象:_LIT(KLiteralDes1,"Jackdawslovemybigsphinxofquartz");TBufC<60>buf(KLiteralDes1);//TBufCaredescribeTPtrptr(buf.Des());//Copyconstruction;canmodifythedatainbufTIntlength=ptr.Length();//Length=TIntmaxLength=ptr.MaxLength();//Maximumlength=60,asforbufTUint8*memoryLocation;//ValidpointerintTIntlen=12;//LengthofdataTIntmaxLen=32;//Maximumlengthtoberepr//ConstructapointerdescriptorfromapointerintomemoTPtr8memPtr(memoryLocation,maxLen);//length=0,maxlenTPtr8memPtr2(memoryLocation,len,maxL符的最大长度,会引发一个系统异常。像TPtrC一样,TPtr也定义了一个Set方法,用来改变描述符所指向的数据。_LIT(KLiteralDes1,"Jackdawslovemybigsphinxofquartz");TBufC<60>buf(KLiteralDes1);//TBufCaredescribeTPtrptr(buf.Des());//PointstothecontentsofbufTUint16*memoryLocation;//ValidpointerintTIntmaxLen=40;//MaximumlengthtobereprTPtrmemPtr(memoryLocation,maxLen);memPtr=ptr;//memPtrdataisKLiteralDes1(37bytes),maxLength=_LIT(KLiteralDes2,"Thequickbrownfoxjumpsoverthelazydog");TBufC<100>buf2(KLiteralDes2);//TBufCaredescribeTPtrptr2(buf2.Des());//Pointstothedatainbuf//Replacewhatptrpointstoptr.Set(ptr2);//ptrpointstocontentsofbuf2,maxlength=100memPtr=ptr2;//AttempttoupdatememPtrwhichpanicsbecause//contentsofptr2(43bytes)exceedsmaxlengthofmemPtr(40bytes)您一定不要混淆了Set()方法和=()赋值操作。前者将改它的最大长度值。述符来讲,字符串数据本身就是描述符的一部分。下图给出了描述符的内存布局:这两种描述符通常用来存储定长的或相对较小的字符串,常用来存放长度小于256个字TBufC<n>是不可修改的缓冲区类型,它主要用来存放字符串常量或是二进制数据。该然后再填充。_LIT(KPalindrome,"Satan,oscillatemymetalTBufC<50>buf1(KPalindrome);//ConstructedfromliteraldesTBufC<50>buf2(buf1);//Constructedf//ConstructedfromaNULL-terminTBufC<30>buf3((TText*)"NeveroddorTBufC<50>buf4;//Constructedempty,lebuf4=buf1;//buf4containsdatacopiedfrombuf1,lengthmodifiedbuf1=buf3;//buf1containsdatacopiedfrombuf3,lengthmodifiedbuf3=buf2;//Panic!Maxlengthofbuf3isinsufficientforbuf2data存区中的数据,该怎么办呢?系统提供了另一种途径来修改数据。该类定义了Des方法,符中的iLength的值会跟着改变,但要记住,缓存区描述符的长度值只可能减小,而是不可能增大的,因为,描述符类是不提供内存管理管理功能的。_LIT8(KPalindrome,"Satan,oscillatemymetalTBufC8<40>buf(KPalindrome);//ConstructedfromliteraldesTPtr8ptr(buf.Des());//dataisthestringinbuf,max//IllustratestheuseofptrtocopyandreplacecontentsofbufASSERT(ptr.Length()==buf.Length(_LIT8(KPalindrome2,"Arewenotdrawnonward,wefew,dptr=KPalindrome2;//Panic!KPalindrome2exceedsmaxlengthofptr(=40)这也是一个模板类,它是一个可修改的缓冲区描述符类,后面的<n>表示缓冲区大小。TBuf从TBufBase类派生,而TBufBase是从TDes派生的方法。像TBufC<n>一样,TBuf<n>也定义了一系列的构造方法和赋值操作。对所有的描述要确保数据长度不要超过缓存区的最大长度。如果需要使用动态分配的内存,您可以使用基于堆的描述符,这个我们在后面要讲到。使用动态数组的额外开销是很高的。_LIT(KPalindrome,"Satan,oscillatemymetalTBuf<40>buf1(KPalindrome);//ConstructedfromliteraldescTBuf<40>buf2(buf1);//ConstructedfromconstantbufferdesTBuf8<40>buf3((TText8*)"DoGeeseseeGod?"TBuf<40>buf4;//Constructedempty,length=0,maximum//Illustratecopyandreplabuf4=buf2;//buf2copiedintobuf4,updatinglengthandmaxlengthbuf3=(TText8*)"Murderforajarofredrum";//updatedfromCstring建者更长的生存期。当您在编译的时候还不能确定缓冲区长度的时候,堆描述符也是很有用的,这时,它的作用相当于C语言中的malloc。也许您已经发现,HBufC的类名以“H”开头,这不符合Symbian系统中惯用的命名习惯。 ()方法,用来在堆上创建一个缓存区。正如您所见到,HBufC中的字母“C”表示这个表述符是不可修改的。对该类的操作几乎和TBufC<n>一样:该类提供了一套赋值操作,允许整异常;通过调用Des()方法,可以返回一个可修改的指针描述符(TPtr可以通过这个指针描述符来更改缓冲区中的内容。_LIT(KPalindrome,"DoGeeTBufC<20>stackBuf(KPali//Allocatesanemptyheapdescriptorofmaxlength20HBufC*heapBuf=HBufC::NewLC(20);TIntlength=heapBuf->Length();//Currentlength=0TPtrptr(heapBuf->Des());//Modificationoftheheapdescriptorptr=stackBuf;//CopiesstackBufcontentsintoheapBuflength=heapBuf->LenHBufC*heapBuf2=stackBuf.AllocLC();//Fromstackbu*heapBuf2=KPalindrome2;//CopyandreplaceCleanupStack::PopAndDestroy(2,的大小。在修改缓存区的内容之前,您要确保缓存区的内存是足够的。为了帮您简化这些操作,HBufC提供的一套ReAllocL()方法,它可以用来扩展堆的缓存区(这个操作有可能会-pointer-asmemory.如果您在HBufC上调用Des()方法来获取了TPtr,在经过重新分配内存后,TPtr中的成员变量iPtr有可能变成无效的。因此,为了确保安全,在重新分配内存后,应该再次调用Des来创建一个新的TPtr对象。注:出于性能上的考虑,Symbian系统并没有提供可修改的堆描述符HBuf。总结:Symbian系统中总共有5种类型的描述符,TPtrC,PTtr,TBufC<n>,TBuf<n>和HBufC。下面的图示表明了它们的继承关系。3.7字面量描述符(LiteralDescr列的宏来创建的,这些宏可在头文件e32def#define_L8(a)(TPtrC8(#define_LIT8(name,s)conststaticTLitC8<sizeo#define_L16(a)(TPtrC16((con#define_S16(a)((co#define_LIT16(name,s)conststaticTLitC16<sizeof(L##name={sizeof(L##s)/2-1,L#首先,我们来看_LIT,这是最有效率也是被使用得最多的一个。这个宏的用法如下:_LIT(KMyLiteralDescriptor,"Thequickbrownfoxjumpsoverthelazydog");后面KMyLiteralDescriptor就可以作为一个常量来使用,例如可以将它写到文件或显示给(在这个例子中是Thequickbrownfoxjumpsoverthelazydog在二进制程序中可以找到这除以2。也有类似的定义。{public:inlineconstTDesC16*operator&()inlineoperatorconstTDesC16&(inlineconstTDesC16&operator()()public: TTextiBuf[AliginlineconstTDesC16*TLitC16<S>::operator&(inlineconstTDesC16&TLitC16<S>::operator()(inlineTLitC16<S>::operatorconstTDesC16&(从上面的定义中可以看到,TLitC16(和TLitC8)并不从TDesC8或TDesC16与TBufC8或TBufC16具有相同的内使用TDesC的地方。您也可以用如下的方法从一个字面量构造一个指针描述符:TPtrC8thePtr(KMyLiteralDesc从字面量构造缓冲区描述符需要一点小技巧。如果您用size去获得_返回相应的TLitC对象的尺寸大小,这个尺寸相当于描述符内容的尺寸加上额外的8个byte必须要将这额外的8个字节考虑进去。_LIT8(KExampleLit8,"Thequickbrownfoxjumpedoverthelazydog");TIntsize=sizeof(KExampleLit8);//52TBufC8<(sizeof(KExampleLit8)-8)>theStackBuffer(KExamp以用更简单的方法,使用操作符来将字面量转换成一个描述符,然后用这个得到的描述符来得到内容的长度。但最简单的方法是,使用操作符将对象转换成描述符后,直接调TIntdescriptorLength=KExampleLit8.iTypeLength;////Formastackbufferdescriptoraroundth//CreateaheapbuffercopyingthecontentsoftheliteralHBufC8*theHeapBuffer=KExampleLit8().Allo//对宽字符字面量的操作类似_LIT16(KExampleLit16,"Thequickbrownfoxjumpedoverthelazydog");size=sizeof(KExampleLit16);//96bytes(codescriptorLength=KExampleLit16.iTypeLength;//44bytes(c用_L和_LIT生成的字面量,它们的内存布局是有差异的,如下图所示:现在我们简单地看看_L和_S宏,这两个宏已经过时,但在测试代码中还经常用到。RDebug::Print(_L("Helloworld!"));这个代码的作用相当于:_LIT(KLit,"Helloworld!");从上面的代码可以看到,使用_L的好处在于,您可以直接使用它,而无需在使用之前,的指针指向字面量的第一个字节在ROM中的存储位置。只要是在创建该字面量的生存期中二进制程序的体积增大。如果仅从存储方式上看,_S宏和_L是相同的,但有一点不同------它不产生临时的TPtrC描述符。如果您仅将它作为以0结尾的描述符使用,那么就使用_S宏。的方法和在使用描述符时一些常见的问题。在编写代码的时候,您可能不想被限制于只能使用TBuf,原因是仅仅因为某个特定的让您的客户也改变他们的代码。这样的改动是非常不理想的,因为它破坏了代码的兼容性。除非您来掌管描述符(负责描述符的创建和销毁工作您甚至可以不用知道描述符是基于堆的还是基于栈的。事实上,只要标准类型的描述符(我们前面提到的5种描述符类型之一就可以在它上面调用适当的方法,客户代码完全可以忽略描述符的内存布局和它在内例如,类RFile定义了read和write方法IMPORT_CTIntWrite(constTDesC8&IMPORT_CTIntRead(TDes8&aDes)在这两个方法中,输入的描述符被显式地声明为8bit的宽度,这样可以既写入字符串,外传递一个参数用来表示返回的数据长度。当写一个函数的时候,如果参数是可修改的描述符生系统异常。当然,您也可能不希望在描述符数据区过短的情况下,描述符的方法会发生系统异常。的描述符。HBufC*CPoem::DoGetLineL(TIntaLineNu{//Codeomittedforclarit//containingthetextofaLineNumber(leavesifaLineNumberis//outofrange)}voidCPoem::GetLineL(TIntaLineNumber,TDes&aD{HBufC*line=DoGetLineL(aLineNum//Isthedescriptorlargeenough(4bytesorm//integerrepresentingthelengthofdatarequired?if(aDes.MaxLength()<line->Length()){if(aDes.MaxLength()>=sizeof(TInt)){//WritesthelengtTPckg<TInt>length(line->Le}//Leave&indicatethatthecUser::Leave(KErrOverflow);//LeavesaredescribedinChapter2{CleanupStack::PopAndDestr}}另一个方案是,在函数中分配堆缓冲区,把它返还给调用者,由调用者负责销毁它。基类TDesC实现了Ptr()方法,用来访问描述符的数据,该方法返回一个指向字符数组首地址的指针。您可以通过这个指针来直接操作字符串数据。代码如下所示:TDesC实现了Size()andLength()方法,前者返回描述符所占有的字节数,而后者返回的是描述符的字符长度。对8bit的描述符来讲,它们是相等的,而对16bit的描述来说,Size(的数值是Length()的两倍。可修改的描述符TDes实现的这个方法返回描述符的最大长度。填充描述符的内容,可用Fill()方法。这个方案类似于C语言中的memse()TDes实现了一系列的重的Copy()方法,下面是其中的两个:IMPORT_CvoidCopy(constTDesC8&IMPORT_CvoidCopy(constTDesC16&如可源描述符的长度超过目标描述符的最大长度,将会引发一个系统异常。我们已经讨论过描述符的一些特性,现在来关注一下使用描述符时经常容易范的错误。首先,我们将创建和使用堆描述符HBufC。前面提到过,在已有的描述符上调用Alloc()()voidCSampleClass::UnnecessaryCodeL(constTDesC&aD{iHeapBuffer=HBufC::NewL(aDes.LeTPtrptr(iHeapBuffer-ptr.Copy(aDes);//以上代码完全可以被下面的代替,下面代码更有效率。iHeapBuffer=aDes.A}Anothercommonwaytointroducecomplexityoccursintheopposdirection,thatis,thegenerationofTDesC&fromaheapdescriptor.了复杂性。代码如下所示:constTDesC&CSampleClass::MoreAccidentalCom{return(iHeapBuffer->Des(//以上代码完全可以写成return(*iHeapBuffer);//这样更简}另外一个比较微妙问题是,当您分配一个HBufC以返回一个TPtr对象。HBufC*buf=HBufC::NewL(9);可是,假如您回忆一下,可以知道在HBufC中,并没有一个字(word)用来保存最大长TPtr需要这个最大长度的信息,这时问题来了,您从哪里得到这个最大长度呢?答案在于:可能并不是您所期望的值(在这个例子中为9)。这是由于您并没有指定一个字对齐(word-aligned)的最大长度,所以们不能确定这个值到底是多少)。{//CreateabufferHBufC8*myBuffer=HBufC8::NewMaxL(KBufferLenTPtr8myPtr(myBuffer-TIntlen=myPtr.Length();/

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论