{ QuarterHours: [{ Minute: { Registered: true, NumAttendees: 1337 }, HourStart: 1 }], Books: ["Game of Thrones", "Harry Potter"], EndDay: 2, StartDay: 3 }
Спецификация FFI # 4.1.1 Объявления импорта ,
impent → "[
static
] [ chname ] [ &] [ cid ] "
| "динамический
"
| «оболочка
»
где chname - это «имя заголовка C», а не «имя библиотеки».
Спецификация FFI № 4.1.4 Спецификация файлов заголовков
AC заголовок, указанный в объявлении импорта, всегда включается с помощью
#include "
chname"
. Нет явной поддержки включения стиля#include <
chname>
. Стандарт ISO C99 [ 3 ] гарантирует, что любой путь поиска, который будет использоваться для#include <
chname>
, также будет использоваться для#include "
chname"
, и гарантируется, что эти пути будут найдены после всех путей, уникальных для#include "
chname"
. Более того, мы требуем, чтобы chname заканчивалось на.h
, чтобы синтаксический анализ спецификации внешних объектов был однозначным.
Попробуйте указать правильное имя заголовка,
foreign import stdcall "hw-driver.h HW_Init" hwInit :: IO CInt
или без имени заголовка в все.
foreign import stdcall "HW_Init" hwInit :: IO CInt
Похоже, в вашей командной строке нет .
как путь поиска библиотеки. Скорее всего, в этом проблема. GHCi волшебным образом включает .
в пути поиска библиотеки.
ghc --make dlltest.hs -L. -lhwdriver
Если это все еще не удается, возможно, это статическая библиотека, которая вызывает проблемы. Маловероятно, но ...
GHC в Windows по умолчанию использует динамическое связывание. Поскольку у вас есть .lib
, которая является статической библиотекой, попробуйте сообщить компоновщику, что вы хотите статическое связывание.
ghc --make dlltest.hs -L. -optl-Bstatic -lhwdriver -optl-Bdynamic
Что касается автоматически сгенерированных привязок, есть
Я обнаружил, что c2hs - самый простой в использовании, но я никогда не пробовал его ни на чем, требующем stdcall
s.
Это не , что обременительно писать все внешние
вещи вручную, если есть только 25 звонки или около того. Несколько лет назад мне удалось вручную написать привязку к libvlc
для небольшого проекта ...
Ниже приведен рабочий пример, который вызывает [GetComputerName] ( http://msdn.microsoft.com/en-us/library/ms724295 (VS.85) .aspx) из kernel32.dll
:
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Control.Monad
import Foreign.C
import Foreign.Marshal.Alloc
import Foreign.Marshal.Array
import System.Win32.Types
foreign import stdcall "GetComputerNameW"
win32_getComputerName :: LPTSTR -> LPDWORD -> IO Bool
getComputerName :: IO String
getComputerName = do
withTString maxBuf $
\buf -> do
alloca $ \len -> do
pokeArray len [fromIntegral maxLength]
success <- win32_getComputerName buf len
when (not success) $ fail "GetComputerName failed"
[len'] <- peekArray 1 len
peekTStringLen (buf, (fromIntegral len'))
where
maxBuf = take maxLength $ repeat 'x'
maxLength = 15 -- cheating
main :: IO ()
main = getComputerName >>= putStrLn
Создайте его с
ghc --make compname.hs -lkernel32