For Programmers: Free Programming Magazines  


Home > Archive > Lisp > March 2006 > Re: CLISP and win32 clipboard access









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Re: CLISP and win32 clipboard access
tsummerall@medialab.com

2006-03-29, 8:01 am

I notice that this example works:

(use-package "FFI")
(def-call-out messagebox
(:name "MessageBoxA") (:library "user32.dll")
(:arguments (hwnd int) (text c-string) (capt c-string)
(type uint))
(:return-type int)
(:language :stdc))

Would it be possible to do something like this from within CLISP
without having to recompile?

I tried this but got only NIL as the return value:

(def-call-out clipget
(:name "GetClipboardData") (:library "user32.dll")
(:arguments (type uint))
(:return-type int)
(:language :stdc))

Is this the right direction to go in at least?

Pascal Bourguignon

2006-03-29, 8:01 am

tsummerall@medialab.com writes:

> I notice that this example works:
>
> (use-package "FFI")
> (def-call-out messagebox
> (:name "MessageBoxA") (:library "user32.dll")
> (:arguments (hwnd int) (text c-string) (capt c-string)
> (type uint))
> (:return-type int)
> (:language :stdc))
>
> Would it be possible to do something like this from within CLISP
> without having to recompile?


Yes.


> I tried this but got only NIL as the return value:


That should not possible. DEF-CALL-OUT returns the name of the lisp
function defined (a symbol, CLIPGET in this case), and the function
CLIPGET should return an integer.

> (def-call-out clipget
> (:name "GetClipboardData") (:library "user32.dll")
> (:arguments (type uint))
> (:return-type int)
> (:language :stdc))
>
> Is this the right direction to go in at least?


Yes.

--
__Pascal Bourguignon__ http://www.informatimago.com/

"This machine is a piece of GAGH! I need dual Opteron 850
processors if I am to do battle with this code!"
Pascal Bourguignon

2006-03-29, 7:03 pm

tsummerall@medialab.com writes:

> Okay, one down two to go. I am now getting a value from the clipboard
> by prefacing it with OpenClipboard().
>
> Any ideas how to coerce the result to a Lisp string?


I don't know anything about Microsoft Windows, but assuming this is it:

http://msdn.microsoft.com/library/d...heclipboard.asp

the first step is to know the signature of the function.

http://msdn.microsoft.com/library/d...ipboarddata.asp

Says that it's: HANDLE GetCliboardData(UINT uFormat);
with:

Return Value

If the function succeeds, the return value is the handle to a
clipboard object in the specified format.

If the function fails, the return value is NULL. To get extended
error information, call GetLastError.

So in any case, the return value is not an int, but a pointer of some kind.

After the examples linked above, it seems you'll need to use
GlobalLock to get a pointer to the data from the returned handle.

If a function returned a string, it would be a simple matter of saying so.

;; http://clisp.cons.org/impnotes/dffi.html

(ffi:def-call-out f (:name "somefun")
(:arguments (arg ffi:c-string))
(:return-type ffi:c-string))

Note that the conversion of the bytes in the c-string is governed by
the ext:*foreign-encoding*, and that the actual encoding used by
MS-Windows seems to depend on the uFormat argument.


You'll have to check MS-Windows headers to see what type a HANDLE is.
Assuming it's a void*, you could declare it as:

(ffi:def-c-type HANDLE ffi:c-pointer)

and then the correct declaration of GET-CLIPBOARD-DATA would be:

(ffi:def-call-out GET-CLIPBOARD-DATA (:name "GetClipboardData")
(:arguments (arg ffi:uint))
(:return-type HANDLE))




If you have to use a lot of MS-Windows functions, it might be
worthwhile to check SWIG to generate the FFI declarations from the
headers.

http://www.cliki.net/SWIG

http://www.cliki.net/Verrazano
http://www.cliki.net/CFFI

--
__Pascal Bourguignon__ http://www.informatimago.com/

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
Pascal Bourguignon

2006-03-29, 7:03 pm

tsummerall@medialab.com writes:

> Okay, for posterity, here it is. Thank you Pascal!!


Here, I think it would be better to use unwind-protect:

> (defun get-clip-string ()
> (clip-open 0)
> (let* ((h (clip-get 1)) (s (global-lock-string h)))
> (global-unlock h) (clip-close 0) s))
>
> (defun set-clip-string (s)
> (let* ((slen (+ 1 (length s)))(newh (global-alloc 8194 slen))
> (newp (global-lock newh)))
> (memcpy newp s (+ 1 slen)) (global-unlock newh) (clip-open 0)
> (clip-set 1 newh) (clip-close 0)))


(defun get-clip-string ()
(let ((s nil))
(unwind-protect
(let* ((dummy (clip-open 0))
(h (clip-get 1)))
(unwind-protect
(setf s (global-lock-string h))
(global-unlock h)))
(clip-close 0))
s))

And similarly in set-clip-string.

--
__Pascal Bourguignon__ http://www.informatimago.com/

COMPONENT EQUIVALENCY NOTICE: The subatomic particles (electrons,
protons, etc.) comprising this product are exactly the same in every
measurable respect as those used in the products of other
manufacturers, and no claim to the contrary may legitimately be
expressed or implied.
Sacha

2006-03-29, 7:03 pm

> If you have to use a lot of MS-Windows functions, it might be
> worthwhile to check SWIG to generate the FFI declarations from the
> headers.
>
> http://www.cliki.net/SWIG
>
> http://www.cliki.net/Verrazano
> http://www.cliki.net/CFFI
>
> --
> __Pascal Bourguignon__ http://www.informatimago.com/
>


I've been recently working a lot with .NET, and found
http://www.pinvoke.net/ to be very usefull.
This web site is providing the .NET world equivalent to FFI for win32 calls.
Wouldn't it be very nice to have such a wiki for FFIs ?

Sacha


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com