📄 object.3
字号:
'\"'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.'\"'\" See the file "license.terms" for information on usage and redistribution'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.'\" '\" SCCS: @(#) @(#) Object.3 1.10 97/07/22 11:40:10'\" .so man.macros.TH Tcl_Obj 3 8.0 Tcl "Tcl Library Procedures".BS.SH NAMETcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared \- manipulate Tcl objects.SH SYNOPSIS.nf\fB#include <tcl.h>\fR.spTcl_Obj *\fBTcl_NewObj\fR().spTcl_Obj *\fBTcl_DuplicateObj\fR(\fIobjPtr\fR).sp\fBTcl_IncrRefCount\fR(\fIobjPtr\fR).sp\fBTcl_DecrRefCount\fR(\fIobjPtr\fR).spint\fBTcl_IsShared\fR(\fIobjPtr\fR).sp\fBTcl_InvalidateStringRep\fR(\fIobjPtr\fR).SH ARGUMENTS.AS Tcl_Obj *objPtr in.AP Tcl_Obj *objPtr inPoints to an object;must have been the result of a previous call to \fBTcl_NewObj\fR..BE.SH INTRODUCTION.PPThis man page presents an overview of Tcl objects and how they are used.It also describes generic procedures for managing Tcl objects.These procedures are used to create and copy objects,and increment and decrement the count of references (pointers) to objects.The procedures are used in conjunction with onesthat operate on specific types of objects such as\fBTcl_GetIntFromObj\fR and \fBTcl_ListObjAppendElement\fR.The individual procedures are described along with the data structuresthey manipulate..PPTcl's \fIdual-ported\fR objects provide a general-purpose mechanismfor storing and exchanging Tcl values.They largely replace the use of strings in Tcl.For example, they are used to store variable values,command arguments, command results, and scripts.Tcl objects behave like strings but also hold an internal representationthat can be manipulated more efficiently.For example, a Tcl list is now represented as an objectthat holds the list's string representationas well as an array of pointers to the objects for each list element.Dual-ported objects avoid most runtime type conversions.They also improve the speed of many operationssince an appropriate representation is immediately available.The compiler itself uses Tcl objects tocache the instruction bytecodes resulting from compiling scripts..PPThe two representations are a cache of each other and are computed lazily.That is, each representation is only computed when necessary,it is computed from the other representation,and, once computed, it is saved.In addition, a change in one representation invalidates the other one.As an example, a Tcl program doing integer calculations canoperate directly on a variable's internal machine integerrepresentation without having to constantly convertbetween integers and strings.Only when it needs a string representing the variable's value,say to print it,will the program regenerate the string representation from the integer.Although objects contain an internal representation,their semantics are defined in terms of strings:an up-to-date string can always be obtained,and any change to the object will be reflected in that stringwhen the object's string representation is fetched.Because of this representation invalidation and regeneration,it is dangerous for extension writers to access\fBTcl_Obj\fR fields directly.It is better to access Tcl_Obj information usingprocedures like \fBTcl_GetStringFromObj\fR..PPObjects are allocated on the heapand are referenced using a pointer to their \fBTcl_Obj\fR structure.Objects are shared as much as possible.This significantly reduces storage requirementsbecause some objects such as long lists are very large.Also, most Tcl values are only read and never modified.This is especially true for procedure arguments,which can be shared between the caller and the called procedure.Assignment and argument binding is done bysimply assigning a pointer to the value. Reference counting is used to determine when it is safe toreclaim an object's storage..PPTcl objects are typed.An object's internal representation is controlled by its type.Seven types are predefined in the Tcl coreincluding integer, double, list, and bytecode.Extension writers can extend the set of typesby using the procedure \fBTcl_RegisterObjType\fR ..SH "THE TCL_OBJ STRUCTURE".PPEach Tcl object is represented by a \fBTcl_Obj\fR structurewhich is defined as follows..CStypedef struct Tcl_Obj { int \fIrefCount\fR; char *\fIbytes\fR; int \fIlength\fR; Tcl_ObjType *\fItypePtr\fR; union { long \fIlongValue\fR; double \fIdoubleValue\fR; VOID *\fIotherValuePtr\fR; struct { VOID *\fIptr1\fR; VOID *\fIptr2\fR; } \fItwoPtrValue\fR; } \fIinternalRep\fR;} Tcl_Obj;.CEThe \fIbytes\fR and the \fIlength\fR members together holdan object's string representation,which is a \fIcounted\fR or \fIbinary string\fRthat may contain binary data with embedded null bytes.\fIbytes\fR points to the first byte of the string representation.The \fIlength\fR member gives the number of bytes.The byte array must always have a null after the last byte,at offset \fIlength\fR;this allows string representations that do not contain nullsto be treated as conventional null-terminated C strings.C programs use \fBTcl_GetStringFromObj\fR to getan object's string representation.If \fIbytes\fR is NULL,the string representation is invalid..PPAn object's type manages its internal representation.The member \fItypePtr\fR points to the Tcl_ObjType structurethat describes the type.If \fItypePtr\fR is NULL,the internal representation is invalid..PPThe \fIinternalRep\fR union member holdsan object's internal representation.This is either a (long) integer, a double-precision floating point number,a pointer to a value containing additional informationneeded by the object's type to represent the object,or two arbitrary pointers..PPThe \fIrefCount\fR member is used to tell when it is safe to freean object's storage.It holds the count of active references to the object.Maintaining the correct reference count is a key responsibilityof extension writers.Reference counting is discussed belowin the section \fBSTORAGE MANAGEMENT OF OBJECTS\fR..PPAlthough extension writers can directly accessthe members of a Tcl_Obj structure,it is much better to use the appropriate procedures and macros.For example, extension writers should neverread or update \fIrefCount\fR directly;they should use macros such as\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead..PPA key property of Tcl objects is that they hold two representations.An object typically starts out containing only a string representation:it is untyped and has a NULL \fItypePtr\fR.An object containing an empty string or a copy of a specified stringis created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.An object's string value is gotten with \fBTcl_GetStringFromObj\fRand changed with \fBTcl_SetStringObj\fR.If the object is later passed to a procedure like \fBTcl_GetIntFromObj\fRthat requires a specific internal representation,the procedure will create one and set the object's \fItypePtr\fR.The internal representation is computed from the string representation.An object's two representations are duals of each other:changes made to one are reflected in the other.For example, \fBTcl_ListObjReplace\fR will modify an object'sinternal representation and the next call to \fBTcl_GetStringFromObj\fRwill reflect that change..PPRepresentations are recomputed lazily for efficiency.A change to one representation made by a proceduresuch as \fBTcl_ListObjReplace\fR is not reflected immediatelyin the other representation.Instead, the other representation is marked invalidso that it is only regenerated if it is needed later.Most C programmers never have to be concerned with how this is doneand simply use procedures such as \fBTcl_GetBooleanFromObj\fR or\fBTcl_ListObjIndex\fR.Programmers that implement their own object typesmust check for invalid representationsand mark representations invalid when necessary.The procedure \fBTcl_InvalidateStringRep\fR is usedto mark an object's string representation invalid and tofree any storage associated with the old string representation..PPObjects usually remain one type over their life,but occasionally an object must be converted from one type to another.For example, a C program might build up a string in an objectwith repeated calls to \fBTcl_StringObjAppend\fR,and then call \fBTcl_ListObjIndex\fR to extract a list element fromthe object.The same object holding the same string valuecan have several different internal representationsat different times.Extension writers can also force an object to be converted from one typeto another using the \fBTcl_ConvertToType\fR procedure.Only programmers that create new object types need to be concernedabout how this is done.A procedure defined as part of the object type's implementationcreates a new internal representation for an objectand changes its \fItypePtr\fR.See the man page for \fBTcl_RegisterObjType\fRto see how to create a new object type..SH "EXAMPLE OF THE LIFETIME OF AN OBJECT".PPAs an example of the lifetime of an object,consider the following sequence of commands:.CS\fBset x 123\fR.CEThis assigns to \fIx\fR an untyped object whose\fIbytes\fR member points to \fB123\fR and \fIlength\fR member contains 3.The object's \fItypePtr\fR member is NULL..CS\fBputs "x is $x"\fR.CE\fIx\fR's string representation is valid (since \fIbytes\fR is non-NULL)and is fetched for the command..CS\fBincr x\fR.CEThe \fBincr\fR command first gets an integer from \fIx\fR's objectby calling \fBTcl_GetIntFromObj\fR.This procedure checks whether the object is already an integer object.Since it is not, it converts the objectby setting the object's \fIinternalRep.longValue\fR memberto the integer \fB123\fRand setting the object's \fItypePtr\fRto point to the integer Tcl_ObjType structure.Both representations are now valid.\fBincr\fR increments the object's integer internal representationthen invalidates its string representation(by calling \fBTcl_InvalidateStringRep\fR)since the string representationno longer corresponds to the internal representation..CS\fBputs "x is now $x"\fR.CEThe string representation of \fIx\fR's object is neededand is recomputed.The string representation is now \fB124\fR.and both representations are again valid..SH "STORAGE MANAGEMENT OF OBJECTS".PPTcl objects are allocated on the heap and are shared as much as possibleto reduce storage requirements.Reference counting is used to determine when an object isno longer needed and can safely be freed.An object just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fRhas \fIrefCount\fR 0.The macro \fBTcl_IncrRefCount\fR increments the reference countwhen a new reference to the object is created.The macro \fBTcl_DecrRefCount\fR decrements the countwhen a reference is no longer needed and,if the object's reference count drops to zero, frees its storage.An object shared by different code or data structures has\fIrefCount\fR greater than 1.Incrementing an object's reference count ensures thatit won't be freed too early or have its value change accidently..PPAs an example, the bytecode interpreter shares argument objectsbetween calling and called Tcl procedures to avoid having to copy objects.It assigns the call's argument objects to the procedure'sformal parameter variables.In doing so, it calls \fBTcl_IncrRefCount\fR to incrementthe reference count of each argument since there is now a newreference to it from the formal parameter.When the called procedure returns,the interpreter calls \fBTcl_DecrRefCount\fR to decrementeach argument's reference count.When an object's reference count drops to zero,\fBTcl_DecrRefCount\fR reclaims its storage.Most command procedures do not have to be concerned aboutreference counting since they use an object's value immediatelyand don't retain a pointer to the object after they return.However, if they do retain a pointer to an object in a data structure,they must be careful to increment its reference countsince the retained pointer is a new reference..PPCommand procedures that directly modify objectssuch as those for \fBlappend\fR and \fBlinsert\fR must be careful tocopy a shared object before changing it.They must first check whether the object is sharedby calling \fBTcl_IsShared\fR.If the object is shared they must copy the objectby using \fBTcl_DuplicateObj\fR;this returns a new duplicate of the original objectthat has \fIrefCount\fR 0.If the object is not shared,the command procedure "owns" the object and can safely modify it directly.For example, the following code appears in the command procedurethat implements \fBlinsert\fR.This procedure modifies the list object passed to it in \fIobjv[1]\fRby inserting \fIobjc-3\fR new elements before \fIindex\fR..CSlistPtr = objv[1];if (Tcl_IsShared(listPtr)) { listPtr = Tcl_DuplicateObj(listPtr);}result = Tcl_ListObjReplace(interp, listPtr, index, 0, (objc-3), &(objv[3]));.CEAs another example, \fBincr\fR's command proceduremust check whether the variable's object is shared beforeincrementing the integer in its internal representation.If it is shared, it needs to duplicate the objectin order to avoid accidently changing values in other data structures..SH "SEE ALSO"Tcl_ConvertToType, Tcl_GetIntFromObj, Tcl_ListObjAppendElement, Tcl_ListObjIndex, Tcl_ListObjReplace, Tcl_RegisterObjType.SH KEYWORDSinternal representation, object, object creation, object type, reference counting, string representation, type conversion
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -