|
Smalltalk/X WebserverDocumentation of class 'ExternalBytes': |
|
|
Class: ExternalBytesInheritance:Object | +--Collection | +--SequenceableCollection | +--ArrayedCollection | +--UninterpretedBytes | +--ExternalBytes | +--ExternalLong | +--ExternalStructure | +--MappedExternalBytes | +--UnprotectedExternalBytes
Description:
This class provides access to any memory in the system. Its main purpose
is to provide a baseclass for objects referencing structured external data.
Normally, instances are created by primitive code which wants to pass C-data
to Smalltalk AND grants smalltalk access to individual bytes afterwards.
Primitives which do not want to grant this access should return instances of
ExternalAddress. See more info there. Also, have a look at ExternalFunction
which is another similar class, but specialized to represent callable C-functions.
Since the memory address of an instance stays fixed (once allocated),
it can also be used to share data with external C-parts
(which are not prepared for objects to change their address).
Use with great care - access is not always checked for out-of-bounds
or valid addresses.
Since the data is allocated outside the garbage collected smalltalk space,
its address stays fix. Thus, it can be passed to external C-functions without
any danger. However, you have to take care for freeing the memory yourself.
To help in avoiding memory bugs, instances created with #new: are
registered in a local classvar and deregistered when the underlying memory
is explicitely freed. Since a life reference (from that classvar) exists,
the garbage collector will never find these to be reclaimable, and the
underlying memory stays allocated (at a fix address) forever.
To release the memory, either #free it or #unprotect it.
The first will immediately release the memory, while the second will delay
freeing until the next garbage collect occurs.
If you need memory which is automatically freed, create
the instance via #unprotectedNew: right away; the underlying malloced-memory
will be released as soon as no smalltalk reference to the ExtBytes object
exists any more (however, you have to know for sure, that no C-references
exist to this memory).
To release all memory call #releaseAllMemory which simply sets the
AllocatedInstances class variable to nil (thus releasing those refs).
Example (automatic freeing as soon as ref to buffer is gone):
|buffer|
buffer := ExternalBytes unprotectedNew:100.
...
Example (manual freeing - never freed, if ref to buffer is gone):
|buffer|
buffer := ExternalBytes new:100.
...
buffer free
Example (delayed automatic freeing as soon as ref to buffer is gone):
|buffer|
buffer := ExternalBytes new:100.
...
buffer unregister
This class only supports unstructured external data
- see the companion class ExternalStructure for more.
Notice: support for external data is still being developed -
a parser for C structure syntax and typedefs is on the way,
making shared data with C programs much easier in the future.
Also notice, that this class may not be available or behave different
in other smalltalk systems, making code using it very unportable.
It is provided for C interfacing only.
Finally note, that ST/X's memory system is much faster than malloc/free
in the normal case - especially for short term temporary objects,
automatically reclaimed object memory is about 5-10 times faster than
malloc/free.
Things may be different for huge byte-valued objects, which are to be
reclaimed by the oldspace colletor.
Anyway, for portability, we strongly warn from using this as a substitute
for byteArrays; it is meant for shared data with external C-functions ONLY.
Debugging:
since all manual memory systems are subject of obscure errors,
you may want to turn malloc-tracing on; this traces all allocations/frees
done here. To do this, evaluate: 'ExternalBytes mallocTrace:true'.
In addition, you may turn on full debugging (with 'ExternalBytes mallocDebug:true');
if turned on, all malloc/realloc requests are remembered and later free / realloc
requests validated against this list (i.e. to detect freeing unallocated chunks).
To benefit from this in C-code, we recommend you use __stx_malloc() / __stx_free()
instead of malloc() / free(). To do so, redefine them in a header file (or cc comand line)
and recompile your external c-libraries with this.
I used this here to find memory leaks in the Xt libraries (there are still some in
the HTML widget ...). If mallocDebug is on, #dumpMallocChunks will print out what is
leftOver. This may help to find trouble spots in your C-code.
Related information:
ExternalAddress
ExternalFunction
ByteArray
[how to write primitive code]
Class protocol:initialization instance creation
Instance protocol:accessing
Examples:These examples below are not directly executable; some require primitive code to be compiled, or are simply given as sceletton. Notice, that in C, indexing is 0-based, while in Smalltalk, indices start at 1. allocating memory in ST, passing it to C: in smalltalk: ... bytes := ExternalBytes new:100. ... in C (assuming that the bytes-object has been passed): ... char *bytePtr; bytePtr = (char *)(__externalBytesAddress(bytes)); if (bytePtr) { ... do something with bytes at bytePtr ... } freeing (in ST): ... bytes free. ... allocating memory in C, passing it to ST: in C: ... char *bytePtr; bytePtr = (char *)(malloc(100)); ... RETURN (__MKEXTERNALBYTES(bytePtr)); in Smalltalk (extracting bytes, integers or strings): byteVal := bytes byteAt:1. ... intVal := bytes doubleWordAt:1 MSB:true. ... string := bytes stringAt:20. ... |data bytes2| data := #[0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0] copy. bytes2 := ExternalBytes new:30. bytes2 replaceBytesFrom:1 to:20 with:data startingAt:1. data replaceBytesFrom:2 to:20 with:bytes2 startingAt:1. bytes2 |data bytes1 bytes2| data := #[0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0]. bytes1 := ExternalBytes new:30. bytes2 := ExternalBytes new:30. bytes1 replaceBytesFrom:1 to:20 with:data startingAt:1. bytes2 atAllPut:99. bytes2 replaceBytesFrom:2 to:21 with:bytes1 startingAt:1. bytes2 asByteArray |data1 bytes1 data2| data1 := #[0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0]. bytes1 := ExternalBytes new:30. bytes1 replaceBytesFrom:1 to:20 with:data1 startingAt:1. data2 := ByteArray new:30 withAll:99. data2 replaceBytesFrom:2 to:21 with:bytes1 startingAt:1. data2 |
|
|
ST/X 6.1.1; WebServer 1.620 at exept:8081; Wed, 23 May 2012 09:03:33 GMT
|