Win32 MessageBox with SBCL foreign interface - common-lisp

I am trying to figure out how to call the Win32 function MessageBox with the SBCL foreign interface. The MessageBox function implemented in "user32.dll" is described as follow:
int MessageBox(
[in, optional] HWND hWnd,
[in, optional] LPCTSTR lpText,
[in, optional] LPCTSTR lpCaption,
[in] UINT uType
);
[...]
MB_OK 0x00000000L The message box contains one push button: OK. This is the default.
The use of this function is trivial using the cffi library:
(cffi:load-foreign-library '(:default "user32"))
(cffi:defcfun ("MessageBoxA" message-box) :int
(hwnd :pointer)
(text :string)
(caption :string)
(type :unsigned-int))
(message-box (cffi:null-pointer) "Hello" "Test" 0)
I tried to use this function directly with the SBCL interface sb-alien: I couldn't make it work.
(sb-alien:load-shared-object "user32")
(defvar c-null (sb-sys:int-sap 0))
(sb-alien:define-alien-routine ("MessageBoxA" MessageBox) sb-alien:int
(hwnd (* sb-alien:integer))
(text sb-alien:c-string)
(caption sb-alien:c-string)
(uType (sb-alien:unsigned 4)))
;; need a small wrapper to convert Lisp's strings to foreign
(defun message-box (title message)
(let ((title-alien (sb-alien:make-alien-string title))
(message-alien (sb-alien:make-alien-string message)))
(MessageBox c-null title-alien message-alien 0)
(sb-alien:free-alien title-alien)
(sb-alien:free-alien message-alien)))
(message-box "Hello" Test")
There isn't any error or warning but it just don't work. How is working the SBCL alien interface? I tried to read the code from CFFI and SBCL, but I could not find any simple example.

I don't understand how I could have spend the whole afternoon on this issue, but the strings are actually automatically converted from/to Lisp. So the code is actually very simple:
(sb-alien:load-shared-object "user32")
(defvar c-null (sb-sys:int-sap 0))
(define-alien-routine ("MessageBoxA" MessageBox) sb-alien:integer
(hwnd (* sb-alien:integer))
(text sb-alien:c-string)
(caption sb-alien:c-string)
(uType (sb-alien:unsigned 4)))
(MessageBox c-null "Hello" "Test" 0)

Related

st-json:write-json - avoid exponent markers for floats

(st-json:write-json-to-string
(st-json:read-json "{\"a\":0.1}"))
Output is not valid JSON:
"{\"a\":1.e-1}"
Desired output:
"{\"a\":0.1}"
I don't see any options or other arguments for write-json-to-string at https://marijnhaverbeke.nl/st-json/
I would still be ok if the number came out a little modified like .1 or 0.10
Update: There is a system variable for float format: "The printer uses *read-default-float-format* to guide the choice of exponent markers when printing floating-point numbers."
According to this example ...
(let ((*read-default-float-format* 'double-float))
(read-from-string "(1.0 1.0e0 1.0s0 1.0f0 1.0d0 1.0L0)"))
==> (1.0d0 1.0d0 1.0 1.0 1.0d0 1.0d0)
The implementation I'm using (SBCL 2.0.11) has float formats F and D. http://www.lispworks.com/documentation/lw50/CLHS/Body/v_rd_def.htm
I'm not sure how "The printer uses *read-default-float-format* to guide the choice of exponent markers when printing floating-point numbers." ... Is there something wrong with my test below?
(progn
(setf *read-default-float-format* 'long-float)
(princ(st-json:write-json-to-string (st-json:read-json "{\"a\":0.1}")))
(setf *read-default-float-format* 'single-float)
(princ(st-json:write-json-to-string (st-json:read-json "{\"a\":0.1}")))
(setf *read-default-float-format* 'double-float)
(princ(st-json:write-json-to-string (st-json:read-json "{\"a\":0.1}")))
(setf *read-default-float-format* 'short-float)
(princ(st-json:write-json-to-string (st-json:read-json "{\"a\":0.1}"))))
{"a":1.e-1}{"a":1.e-1}{"a":1.e-1}{"a":1.e-1}
==> "{\"a\":1.e-1}"
Thanks in advance for any help!
It got nothing to do with *read-default-float-format*.
Using M-. in SLIME, I could see that write-json-to-string calls write-json which in turn calls write-json-element.
write-json-element is a generic function with different methods for different type. method for real is:
(defmethod write-json-element ((element real) stream)
(format stream "~,,,,,,'eE" element))
That format string is standard Common Lisp, resulting in the behaviour you are seeing.
CL-USER> (format t "~,,,,,,'eE" 0.1)
1.e-1
NIL
CL-USER>
I have no idea why author did that, but if you are stuck with st-json, Just redefine the method as (which will issue a re-definition warning, but ignore that):
(defmethod st-json:write-json-element ((element real) stream)
(format stream "~F" element))
However, if you could switch to another library, take a look at jzon, it is in latest Quicklisp.

Clojure's disappearing reflection warnings

A simple reflection warning example:
lein repl
user=> (set! *warn-on-reflection* true)
true
user=> (eval '(fn [x] (.length x)))
Reflection warning, NO_SOURCE_PATH:1:16 - reference to field length can't be resolved.
#object[user$eval2009$fn__2010 0x487ba4b8 "user$eval2009$fn__2010#487ba4b8"]
I want to make this into a function. But where do reflection warnings go?
//clojure/compile.java 63
RT.errPrintWriter()
.format("Reflection warning, %s:%d:%d - reference to field %s can't be resolved.\n",
SOURCE_PATH.deref(), line, column, fieldName);
//clojure/RT.java 269
public static PrintWriter errPrintWriter(){
Writer w = (Writer) ERR.deref();
//clojure/RT.java 188
final static public Var ERR =
Var.intern(CLOJURE_NS, Symbol.intern("*err*"),
new PrintWriter(new OutputStreamWriter(System.err), true)).setDynamic();
Ok so they go to System.err. Lets capture it's output:
(def pipe-in (PipedInputStream.))
(def pipe-out (PipedOutputStream. pipe-in))
(System/setErr (PrintStream. pipe-out))
(defn reflection-check [fn-code]
(binding [*warn-on-reflection* true]
(let [x (eval fn-code)
;_ (.println (System/err) "foo") ; This correctly makes us return "foo".
n (.available pipe-in)
^bytes b (make-array Byte/TYPE n)
_ (.read pipe-in b)
s (apply str (mapv char b))]
s)))
However, calling it gives no warning, and no flushing seems to be useful:
(println "Reflection check:" (reflection-check '(fn [x] (.length x)))) ; no warning.
How can I extract the reflection warning?
You have correctly discovered how *err* is initialized, but since vars are rebindable this is no guarantee about its current value. The REPL often rebinds it to something else, e.g. a socket. If you want to redirect it yourself, you should simply rebind *err* to a Writer of your choosing.
Really I'm not sure your approach would work even if *err* were never rebound. The Clojure runtime has captured a pointer to the original value of System.err, and then you ask the Java runtime to use a new value for System.err. Clojure certainly won't know about this new value. Does the JRE maintain an extra level of indirection to allow it to do these swaps behind the scenes even for people who have already captured System.err? Maybe, but if so it's not documented.
I ran into a similar problem a while back and created some helper functions modelled on with-out-str. Here is a solution to your problem:
(ns tst.demo.core
(:use tupelo.core tupelo.test) )
(defn reflection-check
[fn-code]
(let [err-str (with-err-str
(binding [*warn-on-reflection* true]
(eval fn-code)))]
(spyx err-str)))
(dotest
(reflection-check (quote (fn [x] (.length x)))))
with result:
-------------------------------
Clojure 1.10.1 Java 14
-------------------------------
err-str => "Reflection warning, /tmp/form-init3884945788481466752.clj:12:36
- reference to field length can't be resolved.\n"
Note that binding and let forms can be in either order and still work.
Here is the source code:
(defmacro with-err-str
"Evaluates exprs in a context in which *err* is bound to a fresh
StringWriter. Returns the string created by any nested printing
calls."
[& body]
`(let [s# (new java.io.StringWriter)]
(binding [*err* s#]
~#body
(str s#))))
If you need to capture the Java System.err stream, it is different:
(defmacro with-system-err-str
"Evaluates exprs in a context in which JVM System/err is bound to a fresh
PrintStream. Returns the string created by any nested printing calls."
[& body]
`(let [baos# (ByteArrayOutputStream.)
ps# (PrintStream. baos#)]
(System/setErr ps#)
~#body
(System/setErr System/err)
(.close ps#)
(.toString baos#)))
See the docs here.
There are 5 variants (plus clojure.core/with-out-str):
with-err-str
with-system-out-str
with-system-err-str
discarding-system-out
discarding-system-err
Source code is here.

Defining class and methods in macro

I'm still quite new to Common Lisp macros.
For an abstraction over a defclass with defgeneric I thought it'd be nice to make a macro.
A complitely naive implementation looks like:
(defmacro defgserver (name &key call-handler cast-handler)
"TODO: needs firther testing. Convenience macro to more easily create a new `gserver' class."
`(progn
(defclass ,name (gserver) ())
(defmethod handle-call ((server ,name) message current-state)
,(if call-handler call-handler nil))
(defmethod handle-cast ((server ,name) message current-state)
,(if cast-handler cast-handler nil))))
When used the error says that 'message' is not known.
I'm not sure. 'message' is the name of a parameter of defgeneric:
(defgeneric handle-call (gserver message current-state))
Using the macro I see a warning 'undefined variable message':
(defgserver foo :call-handler
(progn
(print message)))
; in: DEFGSERVER FOO
; (PRINT MESSAGE)
;
; caught WARNING:
; undefined variable: COMMON-LISP-USER::MESSAGE
Which when used has this consequence:
CL-USER> (defvar *my* (make-instance 'foo))
*MY*
CL-USER> (call *my* "Foo")
<WARN> [10:55:10] cl-gserver gserver.lisp (handle-message fun5) -
Error condition was raised on message processing: CL-GSERVER::C: #<UNBOUND-VARIABLE MESSAGE {1002E24553}>
So something has to happen with message and/or current-state.
Should they be interned into the current package where the macro is used?
Manfred
The problem, as mentioned, is that you are talking about different symbols.
However this is really a symptom of a more general problem: what you are trying to do is a sort of anaphora. If you fixed up the package structure so this worked:
(defgserver foo :call-handler
(progn
(print message)))
Then, well, what exactly is message? Where did it come from, what other bindings exist in that scope? Anaphora can be useful, but it also can be a source of obscure bugs like this.
So, I think a better way to do this, which avoids this problem is to say that the *-handler options should specify what arguments they expect. So instead of the above form you'd write something like this:
(defgserver foo
:call-handler ((server message state)
(print message)
(detonate server)))
So here, value of the :call-handler-option is the argument list and body of a function, which the macro will turn into a method specialising on the first argument. Because the methods it creates have argument lists provided by the user of the macro there's never a problem with names, and there is no anaphora.
So, one way to do that is to do two things:
make the default values of these options be suitable for processing into methods without any special casing;
write a little local function in the macro which turns one of these specifications into a suitable (defmethod ...) form.
The second part is optional of course, but it saves a little bit of code.
In addition to this I've also done a slightly dirty trick: I've changed the macro definition so it has an &body option, the value of which is ignored. The only reason I've done this is to help my editor indent it better.
So, here's a revised version:
(defmacro defgserver (name &body forms &key
(call-handler '((server message current-state)
(declare (ignorable
server message current-state))
nil))
(cast-handler '((server message current-state)
(declare (ignorable
server message current-state))
nil)))
"TODO: needs firther testing. Convenience macro to more easily
create a new `gserver' class."
(declare (ignorable forms))
(flet ((write-method (mname mform)
(destructuring-bind (args &body decls/forms) mform
`(defmethod ,mname ((,(first args) ,name) ,#(rest args))
,#decls/forms))))
`(progn
(defclass ,name (gserver) ())
,(write-method 'handle-call call-handler)
,(write-method 'handle-cast cast-handler))))
And now
(defgserver foo
:call-handler ((server message state)
(print message)
(detonate server)))
Expands to
(progn
(defclass foo (gserver) nil)
(defmethod handle-call ((server foo) message state)
(print message)
(detonate server))
(defmethod handle-cast ((server foo) message current-state)
(declare (ignorable server message current-state))
nil))

Remove one method from a generic function

I have added the following method to the generic function speak but would now like to remove this particular method in the REPL without removing the rest of the generic functions' methods.
(defmethod speak :around ((c courtier) string) ; [1]
(format t "Does the King believe that ~A?" string)
(if (eql (read) 'yes)
(if (next-method-p) (call-next-method)) ; [2]
(format t "Indeed, it is a preposterous idea.~%"))
'bow)
[1] The :around method replaces the primary method for the type.
[2] Then it decides whether to call the primary method or not.
The documentation link to the function remove-method has no examples and I don't know what is the syntax to refer to the actual :around method above.
(remove-method #'speak)
TOO FEW ARGUMENTS
(remove-method #'speak :around)
NO-APPLICABLE-METHOD
From the documentation:
remove-method generic-function method
It expects a generic function object and a method object as arguments.
One can find the method via find-method.
CL-USER 39 > (find-method #'speak
(list :around)
(list (find-class 'courtier) (find-class t)))
#<STANDARD-METHOD SPEAK (:AROUND) (COURTIER T) 42001285EB>
CL-USER 40 > (remove-method #'speak
(find-method #'speak
(list :around)
(list (find-class 'courtier)
(find-class t))))
#<STANDARD-GENERIC-FUNCTION SPEAK 422000A68C>
Note also that a good Lisp development environment may also allow to remove methods in the editor or the inspector.
Note that in the Lisp listener, one does not need to call find-method twice like above. The variable * contains the last result.
CL-USER 43 > (find-method #'speak
(list :around)
(list (find-class 'courtier)
(find-class t)))
#<STANDARD-METHOD SPEAK (:AROUND) (COURTIER T) 4200150DEB>
CL-USER 44 > (remove-method #'speak *)
#<STANDARD-GENERIC-FUNCTION SPEAK 422000A68C>
Here is another interaction example using SLIME in GNU Emacs with the presentation feature for SLIME enabled. A presentation is Lisp output, which keeps the connection between the printed object and the generated text.
Call the find-method function. It returns the method. Here we use presentations, which keep the connections between text and Lisp objects. The output is displayed in the color red and it is mouse-sensitive. Moving the mouse over the red returned object will add interaction options.
Now type (remove-method #'speak and then middle-click (or whatever SLIME is configured to use) on the red output: the presentation (the text and the connected object) will be copied to the line. Type ) and enter the form. SLIME has actually constructed a list with the real object and not the textual representation, then.
This is how repls work on the Symbolics Lisp Machine and in CLIM / McCLIM...
If using GNU Emacs with SLIME, you can also use slime-inspector. For example define generic function foo and two methods:
USER> (defgeneric foo (x))
#<STANDARD-GENERIC-FUNCTION FOO (0)>
USER> (defmethod foo ((x string)) (length x))
#<STANDARD-METHOD FOO (STRING) {100B4D7E23}>
USER> (defmethod foo ((x integer)) x)
#<STANDARD-METHOD FOO (INTEGER) {100C355843}>
You have two main options to enter the inspector:
From the REPL, type #'foo so that a presentation object for the generic method is printed:
USER> #'foo
#<STANDARD-GENERIC-FUNCTION FOO (0)>
Either right-click the presentation (anywhere inside #<...>) and select Inspect, or put the cursor in the presentation and press C-c C-v TAB (slime-inspect-presentation-at-point).
From a source file, enter slime-inspect, a.k.a. C-c I, and enter #'foo.
In both cases, you are shown a view similar to this:
#<STANDARD-GENERIC-FUNCTION {505A9A2B}>
--------------------
Name: FOO
Arguments: (X)
Method class: #<STANDARD-CLASS COMMON-LISP:STANDARD-METHOD>
Method combination: #<SB-PCL::STANDARD-METHOD-COMBINATION STANDARD () {1000214003}>
Methods:
(INTEGER) [remove method]
(STRING) [remove method]
(....)
Each [remove method] text is actually a button, click or press Return on any of them to remove the associated method from the generic function.

Print a raw pathname structure

Using CCL, when I print a pathname using, e.g., (format t "~s" pathname), or with pprint, or with print, it prints out with the #P reader syntax. For instance:
? (make-pathname :directory "foo")
#P"foo/"
? (format t "~s" (make-pathname :directory "foo"))
#P"foo/"
NIL
I'd really like to see the underlying pathname structure, so that I can tell exactly what the object looks like. Is there a way to print it raw?
I don't know if that's what you're looking for, but you could call the inspector
(inspect thing)
CCL example:
? (inspect (make-pathname :directory "foo"))
[0] #P"foo/"
[1] Type: PATHNAME
[2] Class: #<BUILT-IN-CLASS PATHNAME>
[3] TYPE: (PATHNAME . #<CCL::CLASS-WRAPPER PATHNAME #x14083886>)
[4] %PATHNAME-DIRECTORY: (:RELATIVE "foo")
[5] %PATHNAME-NAME: NIL
[6] %PATHNAME-TYPE: NIL
[7] %PHYSICAL-PATHNAME-VERSION: NIL
[8] %PHYSICAL-PATHNAME-DEVICE: NIL
Inspect> help
The following toplevel commands are available:
<n> the same as (:I <n>)
(:S N V) set the <n>th line of object data to value <v>
:HOME show first page of object data
:PREV show previous page of object data
:NEXT show next page of object data
:SHOW re-show currently inspected object (the value of CCL:#)
:Q exit inspector
:POP exit current inspector level
(:I N) inspect <n>th item
:? help
:PWD Print the pathame of the current directory
(:CD DIR) Change to directory DIR (e.g., #p"ccl:" or "/some/dir")
(:PROC &OPTIONAL P) Show information about specified process <p>/all processes
(:KILL P) Kill process whose name or ID matches <p>
(:Y &OPTIONAL P) Yield control of terminal-input to process
whose name or ID matches <p>, or to any process if <p> is null
Any other form is evaluated and its results are printed out.
Inspect>
Example on ideone with CLISP
In addition to inspect, you can use describe:
? (describe #P"/tmp/**/file.*")
#P"/tmp/**/file.*"
Type: PATHNAME
Class: #<BUILT-IN-CLASS PATHNAME>
TYPE: (PATHNAME . #<CCL::CLASS-WRAPPER PATHNAME #x30004003ED0D>)
%PATHNAME-DIRECTORY: (:ABSOLUTE "tmp" :WILD-INFERIORS)
%PATHNAME-NAME: "file"
%PATHNAME-TYPE: :WILD
%PHYSICAL-PATHNAME-VERSION: :NEWEST
%PHYSICAL-PATHNAME-DEVICE: NIL
This is a problem with format directives, change "S" with "A" that prints the string, "S" (try to) prints a valid object that can read the REPL or the function read
; SLIME 2016-04-19
CL-USER> (format t "~s" (make-pathname :directory "foo"))
#P"/foo/"
NIL
CL-USER> (format t "~A" (make-pathname :directory "foo"))
/foo/
NIL
from the tutorial a few format receipes
"~S" tries to generate output that can be read back in with READ.
Thus, strings will be enclosed in quotation marks, symbols will be
package-qualified when necessary, and so on. Objects that don't have a
READable representation are printed with the unreadable object syntax
"<>." With a colon modifier, both the ~A and ~S directives emit NIL as
() rather than NIL. Both the ~A and ~S directives also take up to
four prefix parameters, which can be used to control whether padding is > added after (or before with the at-sign modifier) the value, but those
parameters are only really useful for generating tabular data.
finally only to get the string put nil instead of t wich redirect to standard output
CL-USER> (format nil "~A" (make-pathname :directory "foo"))
"/foo/"

Resources