The stub action generated for a method must somehow hook into the
Haskell action that implements it. For IntRef, the component
proxy code in IntRefProxy takes care of this:
module IntRefProxy where
import qualified IntRef
(
State
, set -- :: State -> Int32 -> IO ()
, get -- :: State -> IO Int32
)
import qualified IIntRefProxy
import Com
foreign export stdcall "set" set :: Pointer Interface -> Int32 -> IO HRESULT
set :: Pointer Interface -> Int32 -> IO HRESULT
set = IIntRefProxy.set (IntRef.set :: IntRef.State -> Int32 -> IO ())
foreign export stdcall "get" get :: Pointer Interface -> Pointer Int32 -> IO HRESULT
get :: Pointer Interface -> Pointer Int32 -> IO HRESULT
get = IIntRefProxy.get (IntRef.get :: IntRef.State -> IO Int32)
foreign export stdcall "new" new :: Pointer GUID -> Pointer (Pointer Interface) -> IO HRESULT
new :: Pointer GUID -> Pointer (Pointer Interface) -> IO HRESULT
new piid ppvObject = ...
The component instance constructor, new, is responsible for
creating the binary COM representation of the component at a
particular interface, and details of how it is implemented is
discussed in the next section.
The interface methods simply invoke the interface stubs in
IIntRefProxy, passing the corresponding method implementation as
the first argument:
module IIntRefProxy where
import ComPrim
iidIIntRef :: GUID
iidIIntRef = mkGUID "{C1DF9B10-BDDB-11d1-99CC-006097B7314A}"
set :: (a -> Int32 -> IO ()) -> Pointer Interface -> Int32 -> IO ()
set method_set iptr v = (do
st <- getIfaceState iptr
method_set st v
return s_OK)
`catch` handleCOMError
get :: (a -> IO Int32) -> Pointer Interface -> Pointer Int32 -> IO ()
get method_get iptr ptr = (do
st <- getIfaceState iptr
v <- method_get st
marshallInt32At ptr v
return s_OK)
`catch` handleCOMError
Since each component method takes their state as the first argument,
the interface stubs is responsible for fishing it out. The component
state is accessible via the interface pointer, using
getIfaceState:
getIfaceState :: Pointer Interface -> IO a
The getIfaceState action is provided by H/Direct, and returns the
state associated with an interface pointer (see later section for
details of how it is implemented). It is the responsibility of user's
of IIntRefProxy to ensure that the interface state returned from
getIfaceState is of the type expected by the method action.
The interface stubs are responsible for marshaling arguments and
results to and from the representation expected by the Haskell method,
but in the case of IIntRef's methods, there's little marshaling
to be done.