gpt4 book ai didi

c - 调用某些 win32 api 函数时的 Haskell undefined reference

转载 作者:太空狗 更新时间:2023-10-29 14:56:11 26 4
gpt4 key购买 nike

我正在尝试为一些未包含在 win32 包中的 win32 API 函数编写绑定(bind),但遇到了一些困难。在以下代码中,EnumWindows 和 GetWindow 的绑定(bind)工作正常,但 GetWindowText 和 GetWindowTextLength 的绑定(bind)则不行:

{-# LANGUAGE ForeignFunctionInterface #-}

import Foreign.Ptr
import Graphics.Win32.GDI.Types (HWND)
import System.Win32.Types (ptrToMaybe)
import Foreign.C
import Foreign.Marshal.Alloc (free)
import Control.Applicative ((<$>))

gW_CHILD = 5::CInt

getWindow :: HWND -> CInt -> IO (Maybe HWND)
getWindow hwnd cint = ptrToMaybe <$> (c_getWindow hwnd cint)
foreign import stdcall "windows.h GetWindow"
c_getWindow :: HWND -> CInt -> IO HWND

foreign import stdcall "windows.h EnumWindows"
enumWindows :: (FunPtr (HWND -> Ptr b -> IO a)) -> CInt -> IO CInt

foreign import stdcall "windows.h GetWindowText"
getWindowText :: HWND -> CString -> CInt -> IO CInt

foreign import stdcall "windows.h GetWindowTextLength"
getWindowTextLength :: HWND -> IO CInt

foreign import ccall "wrapper"
wrapEnumWindowsProc :: (HWND -> Ptr a -> IO CInt) -> IO (FunPtr (HWND -> Ptr a-> IO CInt))

findFirstNamedChildWindow :: HWND -> Ptr a -> IO CInt
findFirstNamedChildWindow hwnd _ = do
mchild <- getWindow hwnd gW_CHILD
case mchild of
Just hchwnd -> do
clen <- getWindowTextLength (hchwnd)
case clen of
0 -> return 1
_ -> do
str <- newCString (replicate (fromEnum clen) ' ')
getWindowText hwnd str $ clen+1
print =<< peekCString str
free str >> return 0
Nothing -> return 1
main = do
enptr <- wrapEnumWindowsProc findFirstNamedChildWindow
enumWindows enptr 0
return ()

我收到以下错误消息:

C:\Users\me>ghc nc.hs
Linking nc.exe ...
nc.o:fake:(.text+0x958): undefined reference to `GetWindowText@12'
nc.o:fake:(.text+0xe12): undefined reference to `GetWindowTextLength@4'
collect2: ld returned 1 exit status

所有 4 个函数都在 User32.dll 中。 GHC 版本为 7.8.2(32 位),操作系统为 Windows 7(64 位)。

如果我添加这个 C 文件:

#include <windows.h>

int getWindowText (HWND hwnd, char* str, int len) {
return GetWindowText (hwnd, str, len);
}
int getWindowTextLength (HWND hwnd) {
return GetWindowTextLength (hwnd);
}

并更改导入调用

foreign import call "getWindowText"

foreign import call "getWindowTextLength"

一切正常。到底是怎么回事?关于隐式转换或类似的东西?我尝试了 Foreign.C.String 中的宽字符串函数,但这并没有改变任何东西。 (另外,这是传递字符串缓冲区供 C 写入的预期方法还是有更好的方法?)

最佳答案

大多数处理字符串的 Windows 函数都有两个版本,一个带有 A 的 ANSI 版本后缀和带有 W 的 Unicode 版本后缀。

例如,GetWindowText实际上导出为两个函数,GetWindowTextAGetWindowTextW .这些名称出现在 bottom of the documentation 附近.

LPTSTR参数被解释为 LPSTR对于 A版本和 LPWSTR对于 W版本。您可以使用任一函数,但显然您必须使用适当的字符串类型来配合它。

C 版本有效因为 GetWindowText实际上是一个扩展为 GetWindowTextA 的 C 宏或 GetWindowTextW取决于你是否有 UNICODE宏定义。

关于c - 调用某些 win32 api 函数时的 Haskell undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23468914/

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