% option does an fpreset (floating-point state reset) after the call. Some procedures leave floating-point in an invalid state that causes a crash at some later time. DLL's built with Delphi likely have this problem. If J crashes on simple expressions after calling a procedure, try adding the % option.
declaration is a set of blank delimited codes describing result and parameter types:
c J character (1 byte)
w J unicode (2 byte) (see u:)
s short integer (2 byte)
i integer (4 byte)
l long integer (8 byte)
x J integer (4 byte or 8 byte depending on 32/64)
f short float (4 byte)
d J float (8 byte)
j J complex (16 byte - 2 d values) (pointer only, not as result or scalar)
* pointer
n no result (result, if any, is ignored and 0 is returned)
The first declaration type describes the result and the remaining ones describe the parameters in the cd right argument.
The c w x d j types are native J types. In J32 (32 bit) the i type is the same as x and the l type is an error. In J64 (64bit) the l type is the same as x and the i type is handled similarly to s.
A scalar type (c w s i l x f d j) must have a scalar parameter of the right type. Scalar s i l values take a J integer and f values take a J float.
The * type is a pointer to values. A * can be followed by c w s i l x f d or j to indicate the type of values. The DLL can read or write this memory.
A pointer type parameter must be an array with rank > 1 of the right type, or a scalar boxed scalar integer that is a memory address.
A J integer list used for *s is converted in place to shorts before calling the dll and is converted back after the call. A J integer list used for *i on J64 is converted in place to 4 bytes and then back. A J float list used for a *f is converted in place to short floats and then back.
A *s and *f also allow a character list with a count that is evenly divisible respectively by 2 and 4.
J boolean data is stored as 1 byte values. Boolean parameters are converted to J integers.
J doesn't have unsigned types so DLL unsigned type values with the top bit on are returned to J as negative values.
The mema result (Memory Management) can be used as a * type parameter. A memory address parameter is a boxed scalar. The NULL pointer is <0 .
The cd right argument is a list of enclosed parameters. An empty vector is treated as 0 parameters and a scalar is treated as a single parameter.
The cd result is the procedure result catenated with its possibly modified right argument.
For example, the Win32 API procedure GetProfileString in kernel32 gets the value of the windows/device keyword.
a=: 'kernel32 GetProfileStringA s *c *c *c *c s'
b=: 'windows';'device'; 'default'; (32$'z');32
a cd b
+--+-------+------+-------+--------------------------------+--+
|31|windows|device|default|HP LaserJet 4P/4MP,HPPCL5MS,LPT |32|
+--+-------+------+-------+--------------------------------+--+
The first type s indicates that the procedure returns a short integer. The first pointer names a section. The second pointer names a keyword. The third pointer is the default if the keyword is not found. The fourth parameter is where the keyword text is put. The fifth parameter is the length of the fourth parameter.
If the GetProfileStringA declaration was wrong, say a d result instead of s, it would crash your system. If the fifth parameter was 64 and the keyword was longer than the 32 characters allocated by the fourth parameter, the extra data would overwrite memory.
Procedures are usually documented with a C prototype or a Visual Basic declaration. The C prototype and VB declaration for GetProfileString are:
DWORD GetProfileString(
LPCTSTR lpAppName, // address of section name
LPCTSTR lpKeyName, // address of key name
LPCTSTR lpDefault, // address of default string
LPTSTR lpReturnedString,// address of destination buffer
DWORD nSize // size of destination buffer
);
Declare Function GetProfileString Lib "kernel32"
Alias GetProfileStringA"
ByVal lpAppName As String,
ByVal lpKeyName As String,
ByVal lpDefault As String,
ByVal lpReturnedString As String,
ByVal nSize As Long)
As Long
J declaration types and some corresponding C and VB types are:
c char, byte, bool
s short, short int, word, %
i int, dword
f float, !
d double, #
*c char*, int*, LP..., void*, $
n void
cdf'' unloads all DLLs that cd has loaded. A loaded DLL is in use and attempts to modify it will fail. If you are developing and testing a DLL you must run cdf'' before you can build and save a new version.