It's a wiki: if you are sure of your information, improve it.

[If you're only pretty sure, change it and then send a message to the Forum asking someone to review it.  There is too much to be written for the staff at Jsoftware to write it all]

The standard interface implements call by value (rather than by reference): if you want a result you have to look in the result rather than in the vector that was passed in.

& allows call by reference.  We didn't say much about & in the documentation because making a mistake with & could have catastrophic consequences, even to the point of changing the value of 0.  We wanted to make sure that anyone who used it really understood it: everyone else would follow the standard path of using * and then looking inside the result.

You seem to be in middle ground.  You have figured out how to use &, but it appears from your examples that you don't really need it.  You could have used

cmd=. LIBNAME,' MyIntMod i i *i'
'res' =. cd cmd;nr;XX
newXX =. 3 {:: res

This will make a copy of XX, modify it, and load the changed value into newXX.  Even if XX were in use somewhere else (perhaps, /quelle horreur/, it is 0), nothing will be damaged if it is modified by the DLL.

I suggest that you change your usage to call by value, looking in the result as in my example above.  If for reason of performance you must use &, make sure you don't change the value of 0! And when you fully understand all that, by all means update the Wiki.

Henry Rich



On 3/23/2020 9:51 PM, Scott Locklin wrote:
I haven't called a custom DLL in some time now; since I have more spare
time, I was noodling around with old code.

Took me a while to notice what was going on; "pass by reference" where you
send a J array to a DLL to be written to wasn't working the way it had in
the past. It actually is documented, but I had to read about it in the
forum (this was
<http://jsoftware.2058.n7.nabble.com/j807-cd-pass-array-arguments-td80898.html#a80909>
helpful) to understand what it meant.

I propose that memu be documented here as well as on the "calling DLLs" page

https://code.jsoftware.com/wiki/Guides/DLLs/Memory_Management

Also the use of & vs * in the signature is far from clear to me in the calling
DLL <https://code.jsoftware.com/wiki/Guides/DLLs/Calling_DLLs>s page.
In the past, if I had a function signature like this, and want variable XX
to be populated in the dll (and returned to J), everything would be fine:
(for a C function int MyIntMod (int len, int vec[]) which modifies the
vector of length len )

cmd=. LIBNAME,' MyIntMod i i *i'
XX =. nr $ 1-1
cd cmd;nr;XX
(etc etc)

Now, it only works if I do the following

cmd=. LIBNAME,' MyIntMod i i &i'
XX =. memu nr $ 1-1
cd cmd;nr;XX


Is this the correct way for modify a vector passed by reference in a DLL?
If so, when I read the documentation, it looks like it should work with *i
as well.

"The * type is a pointer to values. A * can be followed by c w u s i l x f d
  or j to indicate the type of values. The DLL can read or write this
memory. The memory is unaliased.

The & type is same as * except the memory is not unaliased as it is assumed
to be constant."
Can someone add a sentence for my (presumably common) dll use case? I was
able to figure it out, but it took me a bit.

-SL
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm


--
This email has been checked for viruses by AVG.
https://www.avg.com

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to