[racket-dev] Calling virtual functions

From: Kovalev Yuriy (yoschi at mail.ru)
Date: Fri Feb 11 17:04:17 EST 2011

Hi all,
I try to reimplement MysterX with new racket-based ffi, but now I have a trouble of calling virtual functions.For be specific, I show a piece of code, a bit of a modified for simplicity:
--------------------#lang racket(require ffi/unsafe (only-in mzlib/defmacro define-macro))
(define ole32 (ffi-lib "ole32"))
;;; ************** Syntax helpers ************************(define-macro (define-ole32 name ole32name . args)  `(define ,name     (get-ffi-obj (quote ,ole32name) ole32       (_fun #:abi 'stdcall , at args -> (status : _uint) -> (and (equal? status 0) result)))))
;;; *********************** GUIDs ************************(define-ole32 progid->clsid CLSIDFromProgID _string/utf-16 (result : (_bytes o 16))); returns clsid (bytes - 128-bit Class ID) from progid (string)
(define IID_IDispatch #"\0\4\2\0\0\0\0\0\300\0\0\0\0\0\0F") ; let it be a constant
;;; ***************** Connect to COM-server *************(define-cpointer-type _com-interface)
(define-ole32 co-create-instance CoCreateInstance  (clsid : _bytes) (_pointer = #f) (_int32 = 21) (refiid : _bytes) (result : (_ptr o _com-interface)))
;;; Probe((get-ffi-obj "CoInitialize" ole32 (_fun (_pointer = #f) (_pointer = #f) -> _int -> (void)))); need to be run once before calling any ole-functions
(define pIdisp (co-create-instance (progid->clsid "Access.Application") IID_IDispatch))------------------------
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?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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20110212/082c719c/attachment.html>

Posted on the dev mailing list.