Как я могу использовать FFI Haskell на структурах? - PullRequest
18 голосов
/ 22 марта 2009

Я создал следующую библиотеку C для чтения изображения:

typedef struct {
    unsigned int height;
    unsigned int width;

    unsigned char* red; //length=height*width
    unsigned char* green;
    unsigned char* blue;
} Contents;

Contents readJPEGFile(const char* inFilename);

Я не могу найти какую-либо информацию, используя массивы и структуры с интерфейсом внешних функций. Как бы я смог использовать свою библиотеку в Haskell?

Я попытался использовать следующий пример в качестве основы: http://therning.org/magnus/archives/315, но затем файл hsc был скомпилирован в файл hs, который содержал только вышеуказанный c-код и ничего более (и, конечно, может компилируется).

Ответы [ 3 ]

10 голосов
/ 22 марта 2009

Базовая поддержка FFI включает только скалярные типы. Все остальное ты делаешь с адресной арифметикой. Раздел о сторонних типах в документации FFI дает основы, и вы можете найти пример в FFI Cookbook .

Когда-то вы могли использовать такие инструменты, как Green Card и H / Direct , чтобы генерировать для вас код маршаллинга и демаршалинга. По причинам, которые я не понимаю, эти инструменты не обновлялись долгое время. Насколько я могу судить, текущий инструмент выбора - hsc2hs.


Редактировать: Как отмечается в комментарии (спасибо ephemient), c2hs также популярен, и, поскольку c2hs от Мануэля Чакраварти, вероятно, будет хорошим.

6 голосов
/ 19 мая 2009

Звучит так, как будто у вас проблема со сборкой; Кажется, я помню, что я использовал ту страницу, на которую вы ссылаетесь, в качестве примера, когда писал интерфейс FFI в библиотеку Windows Win32 DDEML. Например, одна из структур, которые мы используем, это

typedef struct tagHSZPAIR {
    HSZ     hszSvc;
    HSZ     hszTopic;
} HSZPAIR, *PHSZPAIR;

#include "ddeml.h" переносит это в файл DDEML.hsc. Мы получаем к нему доступ:

data HSZPair = HSZPair HSZ HSZ
instance Storable HSZPair where
    sizeOf _                     = (#size HSZPAIR)
    alignment                    = sizeOf
    peek ptr                     = do svc   <- (#peek HSZPAIR, hszSvc)   ptr
                                      topic <- (#peek HSZPAIR, hszTopic) ptr
                                      return $ HSZPair svc topic
    poke ptr (HSZPair svc topic) = do (#poke HSZPAIR, hszSvc)   ptr svc
                                      (#poke HSZPAIR, hszTopic) ptr topic

К сожалению, я не могу показать вам, к чему это компилируется в данный момент, потому что у меня нет удобной коробки Windows, но сгенерированный код был таким же, как указано выше, за исключением того, что #size HSZPAIR заменено на (64) или что-то еще и т. д.

(Если вы действительно хотите посмотреть, что было сгенерировано, или вам нужна помощь в сборке, напишите мне, и я помогу вам.)

0 голосов
/ 22 марта 2009

Hackage имеет несколько пакетов, использующих FFI , с которыми вы можете ознакомиться в качестве примеров.

...