<HTML><BODY>
<div>Hi all,</div><div><br></div><div>I try to reimplement MysterX with new racket-based ffi, but now I have a trouble of calling virtual functions.</div><div>For be specific, I show a piece of code, a bit of a modified for simplicity:</div><div><br></div><div>--------------------</div><div>#lang racket</div><div>(require ffi/unsafe (only-in mzlib/defmacro define-macro))</div><div><br></div><div>(define ole32 (ffi-lib "ole32"))</div><div><br></div><div>;;; ************** Syntax helpers ************************</div><div>(define-macro (define-ole32 name ole32name . args)</div><div> `(define ,name</div><div> (get-ffi-obj (quote ,ole32name) ole32</div><div> (_fun #:abi 'stdcall ,@args -> (status : _uint) -> (and (equal? status 0) result)))))</div><div><br></div><div>;;; *********************** GUIDs ************************</div><div>(define-ole32 progid->clsid CLSIDFromProgID _string/utf-16 (result : (_bytes o 16)))</div><div>; returns clsid (bytes - 128-bit Class ID) from progid (string)</div><div><br></div><div>(define IID_IDispatch #"\0\4\2\0\0\0\0\0\300\0\0\0\0\0\0F") ; let it be a constant</div><div><br></div><div>;;; ***************** Connect to COM-server *************</div><div>(define-cpointer-type _com-interface)</div><div><br></div><div>(define-ole32 co-create-instance CoCreateInstance</div><div> (clsid : _bytes) (_pointer = #f) (_int32 = 21) (refiid : _bytes) (result : (_ptr o _com-interface)))</div><div><br></div><div>;;; Probe</div><div>((get-ffi-obj "CoInitialize" ole32 (_fun (_pointer = #f) (_pointer = #f) -> _int -> (void))))</div><div>; need to be run once before calling any ole-functions</div><div><br></div><div>(define pIdisp (co-create-instance (progid->clsid "Access.Application") IID_IDispatch))</div><div>------------------------</div><div><br></div><div>Now, we have a pointer to Interface (in terms of COM-technology) stored in pIdisp. From this point, work in OO language is very simple. Calling methods of interface looked like pIdsip.QueryInterface(args...), or pIdsip->QueryInterface(args...). I believe, that all work on the dispatch and execution is done by the compiler. But how can I do this using Racket?</div><div>I found, that Interface - is just virtual table of methods. So, for example, pointer to QueryInterface placed in point of IDispatch's address (with no offset) and pointer to method AddRef is placed in offset 4 bytes from IDispatch's address... But I still don't know, how to use it.</div></BODY></HTML>