gpt4 book ai didi

haskell - 消息框错误 : foreign import unsafe

转载 作者:行者123 更新时间:2023-12-02 10:12:14 24 4
gpt4 key购买 nike

import Graphics.Win32
import System.Win32.DLL
import Control.Exception (bracket)
import Foreign
import System.Exit
main :: IO ()
main = do
mainInstance <- getModuleHandle Nothing
hwnd <- createWindow_ 200 200 wndProc mainInstance
createButton_ hwnd mainInstance
messagePump hwnd
wndProc :: HWND -> WindowMessage -> WPARAM -> LPARAM -> IO LRESULT
wndProc hwnd wmsg wParam lParam
| wmsg == wM_DESTROY = do
sendMessage hwnd wM_QUIT 1 0
return 0
| wmsg == wM_COMMAND && wParam == 1 = do
messageBox nullPtr "Yahoo!!" "Message box" 0 -- Error! Why? :(
return 0
| otherwise = defWindowProc (Just hwnd) wmsg wParam lParam
createWindow_ :: Int -> Int -> WindowClosure -> HINSTANCE -> IO HWND
createWindow_ width height wndProc mainInstance = do
let winClass = mkClassName "ButtonExampleWindow"
icon <- loadIcon Nothing iDI_APPLICATION
cursor <- loadCursor Nothing iDC_ARROW
bgBrush <- createSolidBrush (rgb 240 240 240)
registerClass (cS_VREDRAW + cS_HREDRAW, mainInstance, Just icon, Just cursor, Just bgBrush, Nothing, winClass)
w <- createWindow winClass "Button example" wS_OVERLAPPEDWINDOW Nothing Nothing (Just width) (Just height) Nothing Nothing mainInstance wndProc
showWindow w sW_SHOWNORMAL
updateWindow w
return w
createButton_ :: HWND -> HINSTANCE -> IO ()
createButton_ hwnd mainInstance = do
hBtn <- createButton "Press me" wS_EX_CLIENTEDGE (bS_PUSHBUTTON + wS_VISIBLE + wS_CHILD) (Just 50) (Just 80) (Just 80) (Just 20) (Just hwnd) (Just (castUINTToPtr 1)) mainInstance
return ()
messagePump :: HWND -> IO ()
messagePump hwnd = allocaMessage $ \ msg ->
let pump = do
getMessage msg (Just hwnd) `catch` \ _ -> exitWith ExitSuccess
translateMessage msg
dispatchMessage msg
pump
in pump

这是带有按钮的简单 win32 gui 应用程序,但是当我单击按钮时,必须有一个消息框(22 行),但出现错误:

buttons.exe: schedule: re-entered unsafely. Perhaps a 'foreign import unsafe' should be 'safe'?

如何修复它?

最佳答案

正如 Daniel Wagner 评论的那样,这是 Win32 软件包中的一个错误。 MessageBoxW 必须安全导入,因为它有很多副作用。

messageBox 函数是“不安全”导入的 MessageBoxW 函数的包装器。当一个不安全导入的函数函数被不安全导入时,Haskell 假定该线程在返回之前不会调用任何 Haskell 代码。但是,如果您调用 MessageBoxW,Windows 会向您在第 30 行创建的窗口抛出相当多的窗口消息,因此当您处于不安全的外部函数中时,Haskell 代码将会运行。这也是为什么对 messageBox 的调用将起作用直到该窗口被创建。

一个可能的解决方法是简单地自行更正该函数。首先,改变

import Graphics.Win32

import Graphics.Win32 hiding (messageBox, c_MessageBox)

然后,从模块 Graphics.Win32.Misc 中复制 messageBoxc_MessageBox 的定义,其中 unsafe 删除和/或添加安全:

messageBox :: HWND -> String -> String -> MBStyle -> IO MBStatus
messageBox wnd text caption style =
withTString text $ \ c_text ->
withTString caption $ \ c_caption ->
failIfZero "MessageBox" $ c_MessageBox wnd c_text c_caption style
foreign import stdcall safe "windows.h MessageBoxW"
c_MessageBox :: HWND -> LPCTSTR -> LPCTSTR -> MBStyle -> IO MBStatus

关于haskell - 消息框错误 : foreign import unsafe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7304317/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com