Hi!
Does anyone have any good examples of how ExternalStructures are used in Dolphin? In particular, StructurePointers? I'm having real problems accessing the string inside of: StructurePointer newNull: COMTaskMemory elementClass: UnicodeString I keep getting walkbacks all over the place, no matter how I try to get/set the value. Maybe a good question is, is value/value: the way to set the raw value in the structure? thx Eric |
Ok, I've been able to kind of use value/value:. But I had to do some
memory allocation first. I say kind of because if I inspect this: | txt sp | sp := StructurePointer newNull: COMTaskMemory elementClass: UnicodeString. txt := 'some text' asUnicodeString. sp bytes allocate: txt size * 2. sp value: txt. sp value I'll get 'so'. hmmmmm. Do others get similar results? I would expect to get 'some text' as a result. I have a nagging suspicion still that I'm not understanding how to use ExternalStructures well enough. thx for any feedback. Eric Eric Winger wrote: > Hi! > > Does anyone have any good examples of how ExternalStructures are used in > Dolphin? In particular, StructurePointers? > > I'm having real problems accessing the string inside of: > > StructurePointer newNull: COMTaskMemory elementClass: UnicodeString > > I keep getting walkbacks all over the place, no matter how I try to > get/set the value. Maybe a good question is, is value/value: the way to > set the raw value in the structure? > > > thx > > Eric > |
Eric,
> I have a nagging suspicion still that I'm not understanding how to use > ExternalStructures well enough. And I know less about it than you, but I had a little play and came up with sp := StructurePointer newNull: ExternalMemory elementClass: UnicodeString. txt := 'some text' asUnicodeString. sp bytes allocate: txt size * 2. sp replaceFrom: 1 to: txt size * 2 with: txt startingAt: 1. sp value made slightly more complex because of the UnicodeString (the * 2 bits are really a kludge). This appears to work, but!! The problem with the original is that sending #value: to a StructurePointer writes to memory the number of bytes used to hold the ExternalMemory address and not the number of bytes available at the address that it points to (have a think about that - I think it's what I meant). It can therefore only save 4 bytes (the byte size of an address) which is the two UnicodeCharacters you saw. Without knowing how you should really use the class I can only speculate that it needs to override #value: (or maybe #copyBytes:) in a similar way to the way in which it overrides #value. This is just a guess though. Ian |
Ian Bartholomew wrote:
> Eric, > > >>I have a nagging suspicion still that I'm not understanding how to use >>ExternalStructures well enough. >> > > And I know less about it than you, but I had a little play and came up with > > sp := StructurePointer newNull: ExternalMemory elementClass: UnicodeString. > txt := 'some text' asUnicodeString. > sp bytes allocate: txt size * 2. > sp replaceFrom: 1 to: txt size * 2 with: txt startingAt: 1. > sp value > > made slightly more complex because of the UnicodeString (the * 2 bits are > really a kludge). This appears to work, but!! Never let it be said that I'd pass up an opportunity to kludge something. :) > > The problem with the original is that sending #value: to a StructurePointer > writes to memory the number of bytes used to hold the ExternalMemory address > and not the number of bytes available at the address that it points to (have > a think about that - I think it's what I meant). It can therefore only save > 4 bytes (the byte size of an address) which is the two UnicodeCharacters you > saw. > > Without knowing how you should really use the class I can only speculate > that it needs to override #value: (or maybe #copyBytes:) in a similar way to > the way in which it overrides #value. This is just a guess though. > Ok, I think I'm beginning to understand what StructurePointer value: does. And I think its wrong for Strings (or Unicode strings). value/value: should be symmetric. In SP, they're not. Let me explain: (and I might not get some of the details right, but I think the general argument is right) The correct implementation of value/value: should get/set the value of a string in the pointer. value does this. But value: replaces the bytes of the bytes inst var. In my example above, bytes is a subclass of ExternalAddress. Look what happens when you do the following: (StructurePointer newNull: ExternalMemory elementClass: String) value: 'hi' . (StructurePointer newNull: ExternalMemory elementClass: UnicodeString) value: 'hi there' asUnicodeString. The first gets an index error. The second tries to write out of bounds. What is happening is that value: is trying to write the bytes of the strings into the bytes inst var. In this case its a 4 byte memory address of ExternalMemory. It doesn't want a string. I believe it wants an address of the string. This isn't right, it should be symmetric. I made a subclass of StructurePointer -> StringPointer which overrides value: as you suggested. It has just one method. value: aString bytes free. bytes := bytes class fromString: aString. This just changes the ExternalAddress (pointer) of the object as needed and frees the previous pointer. Anyway, I don't know how much value this has on a cosmic or geologic scale, but I think it might be worth a looksie. Eric |
Eric,
> Never let it be said that I'd pass up an opportunity to kludge something. :) Ah, sorry. No insult intended. A(nother) case where the words didn't quite end up reading what I meant to say <g>. I had initially tried to use #byteSize to get the number of bytes to copy, which seemed more "correct", but ran into problems as #byteSize includes the trailing 0 ... x := '123456789' asUnicodeString. x copyFrom: 1 to: x byteSize .. fails. *That* why I referred to the "* 2" as a kludge - honestly. > What is happening is that value: is trying to write the bytes of the > strings into the bytes inst var. In this case its a 4 byte memory > address of ExternalMemory. It doesn't want a string. I believe it wants > an address of the string. This isn't right, it should be symmetric. Hmm, I convinced myself that it was writing to the correct memory address but was only writing the number of bytes that would fit into the space used by an address. Never mind though, whatever it's doing I agree that it is not right. > This just changes the ExternalAddress (pointer) of the object as needed > and frees the previous pointer. That's really just a partial fix though as the underlying reason for #value: failing, that the implementation of #copyBytes: is wrong, means that all (?) the other copy semantics for the object will (might?) be wrong as well. > Anyway, I don't know how much value this has on a cosmic or geologic > scale, but I think it might be worth a looksie. Agreed. It's not a class that is used much but it should still work. Regards Ian |
Free forum by Nabble | Edit this page |