By value means that a parameter is passed "by its value" rather than the address. In newLISP 'import' all integers and floats (yes there are floats now in upcoming release 7400) are passed by value as default. Only strings are passed by address as default. When you do a:
(import "some.lib" "foo")
and call:
(foo 1 2.34 "hello")
The the first parameter '1' will be passed by value the second '2.34. also as a value (internally to 32bit values are pushed on the stack) and "hello" by address, which means the 32bit string address will be pushed onto the stack.
These are the defaults. You also could pass an integer or float value by address doing the following:
(foo (pack "ld" 1) (pack "lf" 2.34) "hello")
So now everything is passed by address. This is very unusual for integers and floats but common and the default for strings.
When it says 'lpText' or 'lpCaption BY ASCIIZ' it means by address the 'ACIIZ' means that it is a ASCII string terminated by a 0 (zero). This works with newLISP, where all strings are zero terminated. newLISP string buffers can also be non ASCIIZ, which means they can have embedded zeroes. In this case the length of it can be retrieved by doing a '(length str)'.
All this was for parameters going
into the function. Sometimes as in the case of GetComputerNameA, the function wants a space where to put the
outgoing result. In this case you have to reserve space and tell it the length of the space you have reserved.
Let me show what I mean with an example using GetWindowsDirectoryA
Code: Select all
(import "kernel32.dll" "GetWindowsDirectoryA")
(set 'str " ")
; reserve enough space, so the name fits
(GetWindowsDirectoryA str (length str))
str => "C:\\WINDOWS\000 "
The second statement reserves space for the result coming back. When you do a 'print' on 'str' you will only see everything up to the \000 (zero). Or you can do a:
(slice str 0 (find "\000" str)) => "C:\\WINDOWS"
to extract it.
Doing the same for "GetComputerNameA" will crash the system, because in this case also the size of the str fields has to be passed as an address:
Code: Select all
(import "kernel32.dll" "GetComputerNameA")
(set 'str " ")
; reserve enough space so the name fits
(set 'lpNum (pack "lu" (length str))) ;; get size in a buffer lpNum
(GetComputerNameA str lpNum) ;; call the function
str => "LUTZ-PC\000 "
(slice str 0 (find "\000" str)) => "LUTZ-PC"
The reason GetComputerNameA wants the size passed by 'LPDWORD' is that the field 'lpNum' serves as both an input and an output field (read the Win32 description of GetComputerName to understand why).
All this works already on 7.3.xx versions (except for pasi9ng floats). This is what you get in 7.4.0:
(1) floats can be passed (see 7.4.0 release manual for example)
(2) up to 14 parameters can be passed (floats count double)
Lutz
ps: 7.4.0 is ready I am still improving docs and it goes online on Wednesday/17th