Вызовите функции C из Haskell во время выполнения - PullRequest
9 голосов
/ 19 июля 2011

Я создаю интерпретатор для языка динамического программирования на Haskell.Я хотел бы добавить простой механизм для вызова функций C.В прошлом я использовал FFI Haskell для вызова функций C, для которых я явно объявил имя и тип;этот подход не будет работать здесь, потому что интерпретатор не будет знать имя или тип функций C, которые будут вызваны до времени выполнения.

Можно ли объявлять и вызывать функции C во время выполнения?С чего мне начать?

1 Ответ

8 голосов
/ 19 июля 2011

Динамический импорт

Если вы можете перечислить все возможные типы для функций C, которые могут быть вызваны, то вы можете использовать возможность динамического импорта FFI (http://www.haskell.org/onlinereport/haskell2010/haskellch8.html).. Функция динамического импорта оборачивает функцию C во время выполнения. Вам потребуется объявить функцию импорта для каждого типа функции C, который вы можете вызывать. (На самом деле, имеет значение только ABI, поэтому вы можете рассматривать все типы указателей C как эквивалентные.)

foreign import ccall "dynamic" mkPtrFun :: FunPtr (Ptr () -> IO (Ptr ())) -> Ptr () -> IO (Ptr ())

Если у вас есть указатель на функцию C, вы можете сделать ее вызываемой из Haskell, используя эту функцию-обертку.

callWithNull :: FunPtr (Ptr a -> IO (Ptr ())) -> IO (Ptr ())
callWithNull f = mkPtrFun f nullPtr

Если типы функций C неизвестны при компиляции кода на Haskell, вы не можете сделать это с помощью FFI.

Динамическая загрузка

Что касается динамического получения указателей на функции C, FFI вам не поможет. Вы можете использовать библиотеки динамической загрузки в C, такие как libdl. Смотрите справочные страницы: http://linux.die.net/man/3/dlopen.

...