Reputation: 3045
I'm trying to pass some data through a C library that doesn't read or modify that data.
foreign import ccall "lua.h lua_pushlightuserdata"
c_lua_pushlightuserdata :: LuaState -> Ptr a -> IO ()
foreign import ccall "lua.h lua_touserdata"
c_lua_touserdata :: LuaState -> CInt -> IO (Ptr a)
data MyData =
MyData
{ dataIds = TVar [Int]
, dataSomethingElse = [String]
}
calledFromRunLuaState :: LuaState -> IO ()
calledFromRunLuaState luaState = do
dataPtr <- c_lua_touserdata luaState (-1)
myData <- dataFromPtr dataPtr
doSomethingWith myData
main = do
luaState <- Lua.newstate
ids <- atomically $ newTVar []
c_lua_pushlightuserdata luaState (dataToPtr (MyData ids []))
runLuaState luaState
I'm trying to figure out how to define dataFromPtr
and dataToPtr
.
Upvotes: 4
Views: 241
Reputation: 23920
This is what StablePtr is for. So you have to use newStablePtr in place of your dataFromPtr
and deRefStablePtr in place of your dataToPtr
. Note that deRefStablePtr
operates in the IO
monad, so you would have to ajust your code accordingly. Also, you would have to adjust the foreign imports to use stable pointers, e.g.:
foreign import ccall "lua.h lua_pushlightuserdata"
c_lua_pushlightuserdata :: LuaState -> StablePtr MyData -> IO ()
and similarly for lua_touserdata
.
Finally, when you create a stable pointer with newStablePtr
, the garbage collector will not deallocate that value automatically. So it is your responsibility to deallocate it by calling freeStablePtr.
Upvotes: 4