我尝试使用来自Haskell的这个简单的C代码:
time_t rawTime = time( NULL );
struct tm* timeInfo = localtime( &rawTime ); /* Using address of a local variable */
printf( "The current date is: %s", asctime( timeInfo ) );
所以我写道:
data CTmStruct = CTmStruct
type CTmStructPtr = Ptr CTmStruct
foreign import ccall "time" c_time :: Ptr CTime -> IO CTime
foreign import ccall "localtime" c_localtime :: Ptr CTime -> IO CTmStructPtr
foreign import ccall "asctime" c_asctime :: CTmStructPtr -> CString
main :: IO ()
main = do
rawTime <- c_time nullPtr
tmStructPtr <- c_localtime ??? -- How to get an address of rawTime?
print $ c_asctime tmStructPtr
那么如何才能获得本地值rawTime
的地址,以便将其作为c_localtime
函数的参数?我已经阅读了Foreign
模块的文档,但我没有找到这个问题的答案。我会非常感谢任何帮助。
答案 0 :(得分:3)
我能够做到:
import Foreign.C.String
import Foreign.Marshal.Alloc
-- Your declarations and foreign bindings here
getTime :: IO String
getTime = do
p <- malloc
c_time p
tmPtr <- c_localtime p
str <- peekCString $ c_asctime tmPtr
free p
return str
main :: IO ()
main = do
currentTime <- getTime
putStrLn currentTime
关键是使用malloc
和free
,您明确分配空间,将其传递给c_time
以设置内容,然后c_localtime
将其格式化为{ {1}},然后将其传递给CTmStruct
以转换为c_asctime
,使用CString
封送回Haskell String
,最后释放用于获取时间。
我想我应该早点意识到这一点,但更好的解决方案是使用peekCString
:
alloca
哪个更安全,更短,更容易。 getTime :: IO String
getTime = alloca $ \p -> do
c_time p
tm <- c_localtime p
peekCString $ c_astime tm
函数为你分配和释放指针,你所要做的就是使用它。