Here you can share completed projects or parts of projects that may be useful to others. You may post files relevant to ZBasic - source code, schematics, etc.
mikep wrote:1. Use Ctrl-space to get an autocompletion list. For example I can type MemAddress with 4 keystrokes: M, e, Ctrl-space, Enter
2. ZBasic allows things to be mixed-case so don't worry about caps
Even if I could type Ctrl-space with one hand, I find autocompletion to be the biggest PITA in the history of the world.
While ZBasic doesn't care about case, I do. It enhances readability which is the main reason for using any Basic dialect. I could do this with PICs and ASM for less cost but that's not as attractive as a DIY project for novices.
But, you're right that I don't understand why CByteArray is needed with MemAddress or VarPtr (which would be my preference).
I don't understand why CByteArray is needed with MemAddress...
MemAddress() and VarPtr() both return an Integer value. MemAddressU() returns an UnsignedInteger value and the .DataAddress property resolves to an UnsignedInteger value as well.
OpenQueue(), GetQueue(), etc. expect to be passed a reference to a Byte array as their first parameter. CByteArray() essentially acts like a "cast" in C/C++, telling the compiler to treat the argument as a reference to a Byte array even though it's integral value. If MemAddress() were allowed to be used as the first parameter so could any other Integer value and there would essentially be no type safety at all.
The current development version allows the .DataAddress property to be used wherever a reference is required. This shortcut would mitigate the need for CByteArray(). This allows one to write:
I'm equivocal about keeping this capability. It is a more general method of skirting the type checking rules than the specialized CByteArray() but it is perhaps more "dangerous" as well.
dkinzer wrote:MemAddress() and VarPtr() both return an Integer value. MemAddressU() returns an UnsignedInteger value and the .DataAddress property resolves to an UnsignedInteger value as well.
The documentation says VarPtr returns an UnsignedInteger.
The current development version allows the .DataAddress property to be used wherever a reference is required. This shortcut would mitigate the need for CByteArray(). This allows one to write:
I'm equivocal about keeping this capability. It is a more general method of skirting the type checking rules than the specialized CByteArray() but it is perhaps more "dangerous" as well.
I noticed that. For me, it's better than CByteArray if I can't use VarPtr. But, stability is even more important so, if you're planning to eliminate the .DataAddress method, I'd rather know that now. I don't want to have to edit my very large app any more than is absolutely necessary.
Dim b as Byte
Sub Main()
Call foo(b.DataAddress)
End Sub
Sub foo(ByRef ival as Integer)
End Sub
This code passes the address of a Byte to a routine that expects to receive the address of an Integer. This may not be particularly useful and, in fact, may be considered dangerous. On the other hand, allowing the .DataAddress to be treated as a "universal reference" simplifies the case we were discussing, i.e. it eliminates the need for CByteAddress(). As you can see, however, it is much more general.
Does VarPtr(b) return the same thing as b.DataAddress?
They have the same value but the compiler treats them slightly differently. The value returned by VarPtr() is indistinguishable from any other UnsignedInteger value. On the other hand, the .DataAddress property, which happens to have an UnsignedInteger value, is distinguished in that it can be used in ways that an arbitrary UnsignedInteger value cannot.
How about VarPtr(InBuf(1, p)) and InBuf(1, p).DataAddress?
Yes, with the same qualification as above. However, v1.1.18 of the compiler erroneously does not accept this VarPtr() construction, complaining that arrays with more than one dimension cannot be passed by reference. This has been rectified in the current development version; likewise for MemAddress() and MemAddressU().
Having used VarPtr for years with VB and PowerBasic, I prefer that construction.
I suspect that you can continue to use VarPtr() in ZBasic in the ways that you might have done so with VB and PowerBasic. If you find cases where this is not so I'd like to be apprised of the details.
dkinzer wrote:I suspect that you can continue to use VarPtr() in ZBasic in the ways that you might have done so with VB and PowerBasic. If you find cases where this is not so I'd like to be apprised of the details.
It sounds like you've already taken away most of the ways I use it in VB and PB. I use it to live dangerously, evading sissy limitations like type checking.
For example, I use VarPtr and the Windows API function RtlMovMemory to get the bytes that represent a single precision variable which I then send to a BX-24 as a stream of bytes and store (using MemAddress & BlockMove) as a single precision variable.
And, I have a year's worth of Dawn/Dusk times stored as an integer array which I need to store in EEPROM. It's faster to transfer in large chunks (i.e. InBuf size) rather than one integer at a time.
The memory images of variables are the same in VB and BasicX so block memory image transfers were the easiest way to transfer data between them.