Как использовать Haskell FFI для структур?

Я создал следующую библиотеку 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-код и ничего больше (и, конечно же, он не может быть скомпилирован).

Ответы

Ответ 1

Звучит так, как будто у вас проблема сборки; Я действительно напоминаю, что я использовал ту самую страницу, которую вы ссылаетесь в качестве примера, когда я писал интерфейс 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) или что-то другое и т.д.

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

Ответ 2

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

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


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