winapi - 在 Windows 上使用 Haskell 模拟击键

标签 winapi haskell hsc2hs

我正在尝试编写一个 Haskell 程序来模拟 Windows 上的击键。我尝试调用 keybd_event 和 SendInput,但都没有编译。不过,我可以用解释器运行该程序。当我尝试构建包含 winable.h 中 SendInput 的绑定(bind)的程序时,出现错误:

cabal install
...
[1 of 2] Compiling WindowsKeys      ( dist\build\WindowsKeys\WindowsKeys-tmp\WindowsKeys.hs, dist\build\WindowsKeys\WindowsKeys-tmp\WindowsKeys.o )
[2 of 2] Compiling Main             ( src\Main.hs, dist\build\WindowsKeys\WindowsKeys-tmp\Main.o )
Linking dist\build\WindowsKeys\WindowsKeys.exe ...
dist\build\WindowsKeys\WindowsKeys-tmp\WindowsKeys.o:fake:(.text+0x35d): undefined reference to `SendInput'
collect2: ld returned 1 exit status
cabal: Error: some packages failed to install:
WindowsKeys-0.1.0.0 failed during the building phase. The exception was:
ExitFailure 1

详细错误位于 http://pastebin.com/trg21N0x ,但似乎并没有更多的线索。当我尝试使用 keybd_event 时,我收到类似的错误。 我编写的 hsc 文件包含以下 header :

#include "windows.h"
#include "winuser.h"
#include "winable.h"

这是 C 绑定(bind):

foreign import ccall unsafe "winable.h SendInput"
        c_SendInput :: UINT
                    -> Ptr Input
                    -> CInt
                    -> IO UINT

我认为由于 #if 的原因,我无法在 winuser.h 上调用 SendInput:

#if (_WIN32_WINNT >= 0x0403)
WINUSERAPI UINT WINAPI SendInput(UINT,LPINPUT,int);

当我为 _WIN32_WINNT 添加绑定(bind)时,该值为 0x400。

我的 Haskell 平台版本为 2012.4.0.0。它带有一个 header 文件夹,其中包含我包含的 header 。我在计算机上找不到任何其他同名的 header 。我使用的是 Windows 7 Professional 版本 6.1。

谢谢!

这是 WindowsKeys.cabal :

-- Initial WindowsKeys.cabal generated by cabal init.  For further 
-- documentation, see http://haskell.org/cabal/users-guide/

name:                WindowsKeys
version:             0.1.0.0
build-type:          Simple
cabal-version:       >=1.8
extra-source-files:  windows.h, winuser.h, winable.h

executable WindowsKeys
  main-is:             Main.hs
  other-modules:       WindowsKeys
  build-depends:       base ==4.5.*, Win32 ==2.2.*
  hs-source-dirs:      src
  build-tools:         hsc2hs
  extra-libraries:     user32
  include-dirs:        src

当我注释掉键盘功能的绑定(bind)时,构建成功。

最佳答案

我终于发现我使用了错误的调用约定。 keybd_eventSendInput 都需要使用 stdcall 调用,而不是 ccall

关于winapi - 在 Windows 上使用 Haskell 模拟击键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19578565/

相关文章:

c++ - 获取文件版本信息失败——但对我来说不是

c++ - 如何将音频字节转换为样本

haskell - 如何使用 StateT、ContT 和 ReaderT 创建 monad?

haskell - GHCI:测试套件的 ghc-options 覆盖库的 ghc-options

haskell - 输出函数名的函数

c - 使用 hsc2hs 时,在 haskell 源代码中引入 #include 指令会导致大量错误

c - winapi scanf printf 和数据类型

c++ - 为什么 WinAPI 对 BOOL 类型使用 int(32 位)?

haskell - 如何为 hsc2hs 枚举成员制作 haddock 文档

c - 如何分配和重用 Haskell 中的 C 结构?