[Openmcl-devel] Win32 questions
Gary Byers
gb at clozure.com
Wed Oct 15 21:18:19 PDT 2014
To digress (hopefully very briefly): lisp objects are dynamically
typed; "foreign objects" generally aren't. "Lisp memory" contains lisp
objects and is managed by a lisp-aware GC; "foreign memory" doesn't
contain lisp objects and is not generally of interest to the GC. C
(and other foreign code) operates on foreign objects in foreign memory
and Lisp code operates on lisp objects in lisp memory, and the twain
only meets in a few places (foriegn function calls and callbacks) in
CCL. There are a few ways of allocating and managing foreign memory
from Lisp code in CCL and of storing and accessing foreign values in
foreign memory; threre is (very intentionally) no way of going in the
other direction in CCL. Some of those ways of allocating foreign
memory allocate it on a stack. Hopefully, that's more than enough of a
digression ...
Using %STACK-BLOCK (as your annotation does) is more correct, but I'd
vote for using
RLET. (All of these things are fairly low-level, but RLET does a
little more for you.)
Recall that a MACPTR is a lisp object that encapsulates some absolute
address. WITH-MACPTRS will bind a set of variables to a set of MACPTR
objects and declares that those variable bindings have dynamic extent
(and therefore the MACPTRs which are the initial values of those
variables can be stack-allocated.) A MACPTR is a few dozem bytes at
most, but code which allocates those small lisp objects on a lisp stack
may CG less frequently than code that allocated them in the lisp heap.
The original code bound SN to a NULL pointer and passed the value of
that null pointer to the foreign fuinction; that's no different than
the other arguments where an explicit null pointer is used.
Your annocation used (%STACK-BLOCK ((SN 32)) ...) That will allocate
32 bytes on a foreign stack and bind SN to a MACPTR to the address of
that memory. If the foreign function call returns with no error, you
could get the value that the function stored there by something like
(%get-unsigned-long sn ; I'm assuming that a DWORD is a 32-bit
unsigned integer
If you don't remember how big a DWORD is (but do remember how to
capitalize it), you could also use RLET and PREF here.
(rlet ((sn #>DWORD))
...
(pref sn #>DWORD))
In C, you might have just said
DWORD sn;
and that's more succinct but it's exactly what the RLET is doing.
On 10/15/2014 02:02:07 PM, Joshua Kordani wrote:
> Greetings all. I am attempting to play with the FFI features of ccl,
> and I've come up with this code snippet that I'd like some feedback
> on.
>
> http://paste.lisp.org/display/144054
>
> according to the win32 api, the function that I call will return 0 on
> error and nonzero on success. In this case, this function is used to
> request various bits of data about a given windows volume, and so all
> of the arguments are optional. arguments are set to defaults with
> null pointers, and the ones that the user would like filled are
> passed in pointers that I imagine are already allocated for the given
> type of data.
>
> In my annotation i changed the with-mactprs macro to the %stack-block
> macro, I guess I didn't really realize that I'm allocating foreign
> memory, or memory that foreign code will write to that I setup is
> considered foreign memory, and then I guess the %stack-block macro is
> the right thing here. Any feedback would be welcome!
>
>--
> Joshua Kordani
> LSA Autonomy
>
------quoted attachment------
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> https://lists.clozure.com/mailman/listinfo/openmcl-devel
>
More information about the Openmcl-devel
mailing list