NB. JDLL example
NB.
NB. This script gives examples of calling the J DLL from J. Similar
NB. routines may be written in other languages that can call DLLs.
NB.
NB. main definitions:
NB. jclear   clear J session
NB. jcmd     send sentence, return result
NB. jdo      send sentence to be executed
NB. jget     retrieve value of J noun
NB. jset     assign value to J noun
NB.
NB. utilities:
NB. jinit    initialize J instance
NB. jfree    free J instance
NB.
NB. Loading the script initializes a J instance, defining
NB. global pJ as the handle. Use jfree to free it.
NB.
NB. see examples at the end of the script.

require 'dll'

NB. =========================================================
i2j=: _2 & ic   NB. binary integer to J
f2j=: _2 & fc   NB. binary float to J
j2i=: 2 & ic   NB. J to binary integer
j2f=: 2 & fc   NB. J to binary float

NB. =========================================================
NB. write memory, return pointer
mwrite=: 3 : 0
p=. mema l=. #y.
y. memw p,0,l
p
)

NB. =========================================================
jclear=: 3 : 0
'j.dll JClear i i' cd pJ
)

NB. =========================================================
jcmd=: 3 : 0
jdo 'JDAT=: ',y.
jget 'JDAT'
)

NB. =========================================================
jdo=: 3 : 0
'j.dll JDo i i *c' cd pJ, boxopen y.
)

NB. =========================================================
NB. jfix
NB. form: trs jfix data_address
NB. trs=type,rank,shape_address
jfix=: 4 : 0
't r s'=. x.
d=. y.,0
len=. */p=. i2j memr s,0,r*4
if. t=1 do. p$ (1{a.)=memr d,len
elseif. t=2 do. p$ memr d,len
elseif. t=4 do. p$ i2j memr d,len*4
elseif. t=8 do. p$ f2j memr d,len*8
elseif. t=16 do. p$ _2 j./\ f2j memr d,len*16
elseif. t=32 do. p$ jgetobj &.> i2j memr d,len*4
elseif. t=64 do. p$ jgetext &> i2j memr d,len*4
elseif. 1 do. 'unrecognized datatype'
end.
)

NB. =========================================================
NB. jfree
jfree=: 3 : 0
'j.dll JFree i i' cd pJ
)

NB. =========================================================
NB. jget
NB. form: jget 'name'
NB. return value of name
jget=: 3 : 0
cmd=. 'j.dll JGetM i i *c *i *i *i *i'
'e p n t r s d'=. cmd cd pJ,(,y.);4#<,0
if. e do.
  wdinfo 'error code: ',":e
  return.
end.
(t,r,s) jfix d
)

NB. =========================================================
NB. jgetobj
NB. form: jgetobj address
jgetobj=: 3 : 0
dat=. y.+12
't c l r'=. i2j memr dat,0 16
(t,r,dat+16) jfix dat+16+r*4
)

NB. =========================================================
NB. jgetext
NB. form: jgetext address
jgetext=: 3 : 0
len=. i2j memr y.,28 4
10000 #. x: |. i2j memr y.,32,4*len
)

NB. =========================================================
NB. jinit
jinit=: 'j.dll JInit i' & cd

NB. =========================================================
NB. jset
NB. form: 'name' jset data
NB. assign value to name
jset=: 4 : 0
rep=. 16}. 3!:1 y.
type=. 3!:0 y.
if. type > 16 do. 'boxed not yet supported' return. end.
rank=. #$y.
shape=. (rank*4){.rep
val=. (rank*4)}.rep
ps=. mwrite shape
pv=. mwrite val
dat=. x.;,each type;rank;ps;pv
e=. 0 pick 'j.dll JSetM i i *c *i *i *i *i' cd pJ,dat
memf ps
memf pv
if. e do.
  wdinfo 'error code: ',":e
end.
empty''
)

NB. =========================================================
NB. check DLL will work!
3 : 0 ''
if. -. IFWIN32 do.
  j=. 'This demo works only under Windows 9x/NT.'
  wdinfo 'JDLL';j
  return.
end.

dll=. tolower each {."1 [ 1!:0 <'*.dll'

if. -. (<'j.dll') e. dll do.
  wdinfo 'JDLL';'Could not find J.DLL'
end.

pJ=: jinit''
)

NB. =========================================================
dllexamples=: 0 : 0
jdo 'ABC=: i.2 3 4'
jget 'ABC'
'ABC' jset i.2 3 4
jcmd 'i.2 3 4'
jcmd '<"0 i.2 3 4'
jclear''
)
