How to dynamically alias a struct to a byte array?
Charles Hixson
charleshixsn at earthlink.net
Sun Feb 17 20:50:35 PST 2013
On 02/17/2013 12:12 PM, jerro wrote:
>> The only thing I've though of so far is to declare a class that holds
>> a bunch of abstract methods, and then have multiple descendants that
>> each have a special variant of the struct. And even then I've either
>> got to copy it again, or to cast it each time I use it. (Though at
>> least with this approach all the casts are located in one area of the
>> code.)
>
> You don't need to cast it each time, you can do something like:
>
> auto structPointer = cast(MyStruct*) byteArray.ptr;
>
> and use structPointer after that (in D structPointer.foo will get the
> member foo, same as (*structPointer).foo). So if you go with the common
> parent approach , you can just store that pointer as a field. This will
> require one extra pointer dereference each time you access the struct,
> though. If you need to access it a lot it may be more efficient to make
> a field of type MyStrtuct and just copy the data to it. The time it
> takes to copy the struct shouldn't really be significant anyway, since
> you are reading it from a file and file IO is typically much slower than
> copying memory.
>
> By the way, if you use the common parent approach, the common parent
> should probably be an interface (http://dlang.org/interface.html), not a
> class.
I don't think the common parent *can* be an interface, as it needs to
hold the byte array. But since the forms of struct that are used by the
byte array are limited, and so are the access methods, I think that a
common "abstract" class would work. (Not really abstract, just with
methods defined unusably.)
..... rambling stuff beyond this point: musing about design issues .....
OTOH, every class access also involves a dereference, so it may well be
better to just use that "auto structPointer = cast(MyStruct*)
byteArray.ptr;" that you mentioned. I'll need to think about that. I
would mean that I wouldn't need to have carefully unimplemented methods
for structs that didn't allow them. But it may really be a logically
better answer, as to get the other to work I'd need to either copy the
byte array, or to create an instance of the root class (so I couldn't
really be abstract, but would just need to have methods implemented as
bool example(params) { assert(false, "This method shouldn't be used"); }
Still, as you mentioned copying the data isn't usually too high a price
when it's done near alongside an IO request.
Than again, I always worry about mixing pointers and garbage collection.
I'll need to read that section of the documentation again. Two or
three times. Perhaps five. (Pointers are the MAIN reason I was happy
to abandon C for Python/Ruby/Java/Eiffel/Smalltalk/... a decade or so
ago. I'm really an old FORTRAN IV programmer, who was happy to move to
PL/I because it made EBCDIC character handling easier. These days read
unicode instead of EBCDIC. But pointers still make me uneasy. The feel
too much like dropping into assembler.)
So what I'll probably end up doing is defining lots of separate structs
that each take a byte array for a constructor argument. If I'm going to
use them often enough, that might even be faster, and it will almost
certainly be more intelligible a few months after I write it. And I may
end up nesting them within a class anyway so that I can call them
without needing to know exactly which kind I'm calling. Well, actually
if I'm going to build a class, then I won't need that kind of
complexity, because a lot of the "different kinds of struct" is just so
that the data can easily be read in from and written out to a file.
Which means static array sizes. So I was thinking of having a few
custom sizes of struct based around different amounts of data in various
parts, but if I'm going to be using a class as the access, then I can
just use dynamic arrays, and build (or parse) the byte array each time I
do IO. Which means multiple dereferences, but which is enough simpler
than the other approach that it may pay for itself.
More information about the Digitalmars-d-learn
mailing list