memoryEventHookAdd :: Storable a
                   => Engine                -- ^ 'Unicorn' engine handle
                   -> MemoryEventHookType   -- ^ An invalid memory access (e.g.
                                            -- read, write, etc.) to trigger
                                            -- the callback on
                   -> MemoryEventHook a     -- ^ Invalid memory access callback
                   -> a                     -- ^ User-defined data. This will
                                            -- be passed to the callback
                                            -- function
                   -> Word64                -- ^ Start address
                   -> Word64                -- ^ End address
                   -> Emulator Hook         -- ^ The hook handle on success, or
                                            -- an 'Error' on failure
memoryEventHookAdd uc memEventHookType callback userData begin end = do
    result <- lift . alloca $ \userDataPtr -> do
        poke userDataPtr userData
        funPtr <- marshalMemoryEventHook callback
        getResult $ ucHookAdd uc memEventHookType funPtr userDataPtr begin end
    hoistEither result

-- | Unregister (remove) a hook callback.
memoryEventHookAdd :: Storable a
                   => Engine                -- ^ 'Unicorn' engine handle
                   -> MemoryEventHookType   -- ^ An invalid memory access (e.g.
                                            -- read, write, etc.) to trigger
                                            -- the callback on
                   -> MemoryEventHook a     -- ^ Invalid memory access callback
                   -> a                     -- ^ User-defined data. This will
                                            -- be passed to the callback
                                            -- function
                   -> Word64                -- ^ Start address
                   -> Word64                -- ^ End address
                   -> Emulator Hook
memoryEventHookAdd uc memEventHookType callback userData begin end = do
    result <- lift . alloca $ \userDataPtr -> do
        poke userDataPtr userData
        funPtr <- marshalMemoryEventHook callback
        getResult $ ucHookAdd uc memEventHookType funPtr userDataPtr begin end
    hoistEither result

-- | Unregister (remove) a hook callback.
memoryEventHookAdd uc memEventHookType callback userData begin end = do
    result <- lift . alloca $ \userDataPtr -> do
        poke userDataPtr userData
        funPtr <- marshalMemoryEventHook callback
        getResult $ ucHookAdd uc memEventHookType funPtr userDataPtr begin end
    hoistEither result

-- | Unregister (remove) a hook callback.