Tôi đang cố gắng viết các ràng buộc với một số hàm win32 API không có trong gói win32, nhưng chạy vào một chút khó khăn. Trong đoạn mã sau các ràng buộc cho EnumWindows và làm việc tốt GetWindow, nhưng những người cho GetWindowText và GetWindowTextLength không:Haskell tham chiếu không xác định khi gọi một số chức năng win32 api
{-# 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()
tôi nhận được thông báo lỗi sau:
C:\Users\me>ghc nc.hs
Linking nc.exe ...
nc.o:fake:(.text+0x958): undefined reference to `[email protected]'
nc.o:fake:(.text+0xe12): undefined reference to `[email protected]'
collect2: ld returned 1 exit status
Tất cả 4 chức năng đang trong User32 .dll. Phiên bản GHC là 7.8.2 (32 bit), hệ điều hành là Windows 7 (64).
Nếu tôi thêm C tập tin này:
#include <windows.h>
int getWindowText (HWND hwnd, char* str, int len) {
return GetWindowText (hwnd, str, len);
}
int getWindowTextLength (HWND hwnd) {
return GetWindowTextLength (hwnd);
}
và thay đổi khẩu gọi
foreign import call "getWindowText"
foreign import call "getWindowTextLength"
mọi thứ hoạt động như mong đợi. Điều gì đang xảy ra? Một cái gì đó về phôi tiềm ẩn hoặc một cái gì đó như thế? Tôi đã thử các chức năng chuỗi rộng từ Foreign.C.String nhưng điều đó không thay đổi bất cứ điều gì. (Ngoài ra là cách dự định để vượt qua một bộ đệm chuỗi cho C để ghi vào hoặc là có một phương pháp tốt hơn?)
Cảm ơn, 'ngoại nhập stdcall" windows.h GetWindowTextLengthA "' hoạt động tốt. –