I�m having problems connecting a Visual C++ interface and some Lisp code,
partly because of skimpy documentation in Corman Lisp and mostly because I
don�t know C++ and general principles of foreign function interface.
Corman Lisp can create Lisp functions which can be called by C++ programs,
and pointers to those functions. I have two questions:
1. How do you use the pointer in C++ to actually call the Lisp
function. Suppose x is the pointer, and the function has two arguments.
Is that the construction:
(*x) (arg1, arg2) ?
Suppose the pointer were stored in a C++ array, say as the 0th value.
Would the function call be the C++ equivalent of :
( * svref(array 0)) (arg1, arg2)
2. How is the pointer passed to the C++ program? If both of the
following methods work, which is better?
a. Corman Lisp has an example of calling a C++ function from Lisp.
Would this work:
i. Define a C++ function, store_values, which stores its
arguments in an array, ARR.
ii. In the Lisp program, after the desired pointers to Lisp
foreign functions are created, put in a call to store_values with the
pointers as args.
Store_values would be declared EXTERN. Would that also be true
for the array?
b. Corman Lisp has an example of Lisp code doing C-like things,
including allocating space for an array and storing the value of a foreign
function pointer in the array. The relevant snippet is:
(setf (cref WNDCLASSEX wndclass lpfnWndProc) (get-callback-procinst
'WndProc-devcaps1))
WndProc-devcaps1 is a Lisp function which can be called by C++, and
get-callback-procinst returns the pointer to the function. Unfortunately,
neither �WNDCLASSEX� nor �lpfnWndProc� is defined in the file. What are
they? Is the first an external C++ array? What�s �lpfnWndProc�? wndclass
is defined:
(let
...
(wndclass (ct:malloc (sizeof 'WNDCLASSEX)))
What has to be in the C++ program for this to work? For completeness, the
file in which this snippet appeared is included. It appeared in the last
function, WinMain-devcaps1.
;;;;
;;;; File: devcaps1.lisp
;;;; Contents: Simple Windows demonstration app, from Petzold's
;;;; Programming Windows 95
;;;;
(in-package :win32)
(defconstant szAppName "DevCaps1")
(defstruct info index label desc)
(defvar *devcaps*
(list
(make-info :INDEX HORZSIZE :LABEL "HORZSIZE" :DESC "Width in
millimeters:")
;;;Many other entries omitted.
))
(defvar *ps* nil)
(defvar *tm* nil)
(ct:defun-callback WndProc-devcaps1 ((hwnd HWND)(iMsg UINT)(wParam
WPARAM)(lParam LPARAM))
;;Rest of function definition omitted. The Ct:defun-callback ;;defines
a Lisp function that can be called from C++. This ;;function definition
doesn�t use the undefined terms above -- ;;WNDCLASSEX and lpfnWndProc
(defun WinMain-devcaps1 (hInstance hPrevInstance szCmdLine iCmdShow)
(let ((hwnd NULL)
(msg (ct:malloc (sizeof 'MSG)))
(wndclass (ct:malloc (sizeof 'WNDCLASSEX)))
(*ps* (ct:malloc (sizeof 'PAINTSTRUCT)))
(*tm* (ct:malloc (sizeof 'TEXTMETRIC))))
(setf (cref WNDCLASSEX wndclass cbSize) (sizeof 'WNDCLASSEX))
(setf (cref WNDCLASSEX wndclass style) (logior CS_HREDRAW CS_VREDRAW))
(setf (cref WNDCLASSEX wndclass lpfnWndProc) (get-callback-procinst
'WndProc-devcaps1))
(setf (cref WNDCLASSEX wndclass cbClsExtra) 0)
(setf (cref WNDCLASSEX wndclass cbWndExtra) 0)
(setf (cref WNDCLASSEX wndclass hInstance) hInstance)
(setf (cref WNDCLASSEX wndclass hIcon) (LoadIcon NULL IDI_APPLICATION))
(setf (cref WNDCLASSEX wndclass hCursor) (LoadCursor NULL IDC_ARROW))
(setf (cref WNDCLASSEX wndclass hbrBackground) (GetStockObject
WHITE_BRUSH))
(setf (cref WNDCLASSEX wndclass lpszMenuName) NULL)
(setf (cref WNDCLASSEX wndclass lpszClassName) (ct:create-c-string
szAppName))
(setf (cref WNDCLASSEX wndclass hIconSm) (LoadIcon NULL IDI_APPLICATION))
(RegisterClassEx wndclass)
(setq ghwnd
(CreateWindowEx 0
(ct:create-c-string szAppName) ;; window class name
(ct:create-c-string "Device Capabilities") ;; window caption
WS_OVERLAPPEDWINDOW ;; window style
CW_USEDEFAULT ;; initial x position
CW_USEDEFAULT ;; initial y position
CW_USEDEFAULT ;; initial x size
CW_USEDEFAULT ;; initial y size
(cl::get-application-main-window) ;; parent window handle
NULL ;; window menu handle
hInstance ;; program instance handle
NULL)) ;; creation parameters
(ShowWindow ghwnd iCmdShow)
(UpdateWindow ghwnd)
(do ((ret (GetMessage msg NULL 0 0)(GetMessage msg NULL 0 0)))
((not ret))
(TranslateMessage msg)
(if (= (cref MSG msg message) WM_QUIT)
(return))
(DispatchMessage msg))
(cref MSG msg wParam)))
(defun test-devcaps1 ()
(setq instance (cl::get-application-instance))
(winmain-devcaps1 instance null (ct:create-c-string "") SW_SHOW))
Thanks.
Neil
Neil Cohen
Bridge Trix
Producers of the Bobby Wolff Bridge Mentoring Series
http://www.bridgetrix.com
······@bridgetrix.com writes:
> I�m having problems connecting a Visual C++ interface and some Lisp code,
> partly because of skimpy documentation in Corman Lisp and mostly because I
> don�t know C++ and general principles of foreign function interface.
> [...]
Neil, you are right in that to do what you want, you have to be
familiar with C (the questions you ask are not C++ specific) and
Windows API concepts. You do not have to be a wizard, but knowing C
data types and their machine representation, function calling
convention, and what is WNDCLASSEX are among the things that should be
sort of obvious. If you are serious about interfacing with C and
doing some Windows API programming, you cannot avoid studying that.
Your best bet would be to get a book or two and study some C
programming and Windows API. If you still have questions after you've
done so, that would at least help you formulate them properly. Beyond
C basics, there are not too many FFI principles that are not apparent
from reading sys\ffi.lisp.
Hope this helps,
--Vassili
Vassili Bykov <·······@objectpeople.com> wrote:
> ······@bridgetrix.com writes:
>
> > I�m having problems connecting a Visual C++ interface and some Lisp code,
> > partly because of skimpy documentation in Corman Lisp and mostly because I
> > don�t know C++ and general principles of foreign function interface.
> > [...]
>
> Neil, you are right in that to do what you want, you have to be
> familiar with C (the questions you ask are not C++ specific) and
> Windows API concepts. You do not have to be a wizard, but knowing C
[snip]
> Your best bet would be to get a book or two and study some C
> programming and Windows API. If you still have questions after you've
I strongly recommend "Win32 Programming", by Brent E. Rector and
Joseph M. Newcomer, ISBN 0-201-63492-9. Not a C beginner's book but
_very_ complete and detailed on all the screwy Win32 bits.
This is now way off topic, so we should probably drop it...
Dan Pierson, Control Technology Corporation
···@control.com