Haskell внешний импорт stdcall на функции DLL

  1. Вы просто отправляете и ссылаетесь на него таким же образом.
  2. Вы передадите (вот как это выглядит, когда вы получаете его с сервера):
{
    QuarterHours: [{
        Minute: {
            Registered: true,
            NumAttendees: 1337
        },
        HourStart: 1
    }],
    Books: ["Game of Thrones", "Harry Potter"],
    EndDay: 2,
    StartDay: 3
}
11
задан Don Stewart 17 April 2011 в 21:26
поделиться

2 ответа

Спецификация 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 для небольшого проекта ...

5
ответ дан 3 December 2019 в 10:44
поделиться

Ниже приведен рабочий пример, который вызывает [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
3
ответ дан 3 December 2019 в 10:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: