Guides/DLLs/Calling the J DLL
Here, the term DLL is used for any J shared library, i.e. j.dll (Windows), libj.so (Linux) and libj.dylib (OSX).
The J DLL can be called by any program that can call DLLs.
Since j.dll is itself used by the J session, you may need to make a copy of it first before calling it from J, for example, copy it to file jj.dll.
Script ~addons/general/misc/jdll.ijs has examples of calling the J DLL from J.
Examples
In the following examples libj is assumed defined as the J DLL.
Initialize the DLL, returning a pointer to J:
p=. (libj,' JInit x') cd '' ┌────────┐ │53024912│ └────────┘
Procedure JDo executes a sentence. For example, the following writes text abc to file t1.txt:
cmd=. '''abc'' 1!:2 <''t1.txt''' NB. example sentence (libj,' JDo i x *c') cd p,<cmd NB. send to J DLL ┌─┬────────┬────────────────────┐ │0│53024912│'abc' 1!:2 <'t1.txt'│ └─┴────────┴────────────────────┘ fread 't1.txt' NB. check file was written abc
Procedure JGetM retrieves a J variable. The cd right argument is a name, followed by 4 pointers, which will correspond to the result datatype, rank, pointer to shape, and pointer to values. For example:
(libj,' JDo i x *c') cd p,<'AA=: o.i.2 3 5' NB. define AA ┌─┬────────┬──────────────┐ │0│53024912│AA=: o.i.2 3 5│ └─┴────────┴──────────────┘ (libj,' JGetM i x *c *x *x *x *x') cd p,'AA';4#<,0 NB. read AA ┌─┬────────┬──┬─┬─┬────────┬────────┐ │0│53024912│AA│8│3│71648552│71648576│ └─┴────────┴──┴─┴─┴────────┴────────┘
The seven items in the result are: error code (0=success), j pointer, name, datatype (4=integer), rank(1), pointer to shape, and pointer to values.
The pointers refer to memory addresses within the J DLL. You should reference their values before calling the J DLL again, as further calls may invalidate the memory addresses. Use function memr to read the memory. For example, the shape is:
memr 71648552 0 3 4 2 3 5
Once the result datatype and shape are known, you can read the values, again using memr, and convert to a J variable.
Script ~addons/general/misc/jdll.ijs defines functions that perform the necessary conversions. For example:
load'general/misc/jdll' jinit'' ┌────────┐ │23017632│ └────────┘ jdo 'ABC=: i.3 4' ┌─┬────────┬───────────┐ │0│21939088│ABC=: i.3 4│ └─┴────────┴───────────┘ jget 'ABC' 0 1 2 3 4 5 6 7 8 9 10 11 jcmd 'q: 123456' 2 2 2 2 2 2 3 643