我正在测试incline-c
的win32 api。
我意识到LPCTSTR
没有IsString
实例。
但是我不知道怎么写。
有提示吗?
有关信息:
type LPTSTR = Ptr TCHAR
type TCHAR = CWchar
在System.Win32.Types
中定义
和
newtype CWchar
Haskell type representing the C wchar_t type.
Constructors
CWchar Int32
这是我的代码:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
import Data.String
import qualified Language.C.Inline.Win32 as CW
import qualified Language.C.Inline as C
import System.Win32.Types
instance IsString LPCTSTR where
C.context CW.win32Ctx
C.include "<windows.h>"
showMsg :: LPCTSTR -> IO INT
showMsg s = do
[C.exp| INT{ MessageBox( NULL, $(LPCTSTR s), "Haskell Rocks", MB_OK )} |]
main = showMsg "Hello Haskell"
编辑: 我设法用ByteString实现了这一点
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
import qualified Data.ByteString as BS
import qualified Language.C.Inline.Win32 as CW
import qualified Language.C.Inline as C
import System.Win32.Types
C.context (CW.win32Ctx <> C.bsCtx)
C.include "<windows.h>"
showMsg :: BS.ByteString -> IO INT
showMsg s = do
[C.exp| INT{ MessageBox( NULL, $bs-ptr:s, "Haskell Rocks", MB_OK )} |]
main = showMsg "Hello Haskell"
答案 0 :(得分:4)
由于无法使用CString完成此实例,因此无法合理地定义此实例:指向char的指针不能执行内存管理。因此,在运行时生成C字符串对于悬挂内存是不安全的,否则会导致内存泄漏。
原则上应该可能的是尽管如此,仍然可以访问字符串文字,这在C本身中也是可行的:只需分配静态内存位置编译时间一次。但是IsString
类不支持此功能。
总结:C字符串在Haskell中很难使用,因此最好仅在C代码的接口上直接使用它们。即如果您甚至使用C [w]字符串围绕C函数编写了低级包装,则应使用String
或Text
作为参数。围绕C调用将其转换为IO块中合适的C字符串,并与unsafePerformIO
一起“净化”它们。