Haskell FFI для C рекурсивной структуры и объединения - PullRequest
3 голосов
/ 12 ноября 2011

Я пытаюсь написать привязку Haskell FFI для некоторых структур Си. Пример ниже:

typedef struct s0{int a; 
                  union{unsigned char b; 
                        struct s0*c; 
                        struct{unsigned char d[1];
                         }; };}*S;

У меня вопрос, как написать для него привязку в формате chs (для c2hs ) или hsc (для hsc2hs ) ? Я просмотрел учебники по c2hs, но либо не получил достаточно информации, либо не понял ее так, чтобы это помогло мне написать файл chs для приведенного выше определения.

Я могу сгенерировать привязки haskell, используя инструмент HSFFIG, но он использует специальный метод доступа HSFFIG.FieldAccess.FieldAccess для определения привязок. Я предпочитаю писать привязки, использующие базовые библиотеки haskell FFI, а не сторонние библиотеки.

Следовательно, этот вопрос о том, как написать привязку для рекурсивной структуры выше в формате hsc или в формате chs, который использует только основные библиотеки FFI.

Фактическое определение является более сложным, но как только я пойму, как написать приведенное выше определение структуры для инструментов c2hs или hsc2hs, я могу перейти оттуда. Я знаю, что сохраняемые экземпляры должны быть определены для внутреннего объединения и структуры, но я не знаю, как писать обертки для рекурсивного определения, как описано выше. Особенно, как вы получаете доступ внутри структуры / объединения из внешней структуры? Я изучил определения HSFFIG, но методы доступа - это методы доступа, определенные HSFFIG. Поэтому я не смог понять, как перевести его в определение chs, в котором используются только основные библиотеки FFI.

Вопросы, которые я видел в StackOverflow, касаются более простых определений. Если где-то есть аналогичный ответ, я буду признателен за указатели.

1 Ответ

1 голос
/ 22 ноября 2011

Вы не можете замаскировать эквивалентную структуру данных ни в c2hs, ни в hsc2hs. Тем не менее, вы можете сделать свой собственный маршалинг в c2hs с небольшой работой.

data MyType = Next MyType | MyChar Char | MyString String | MyEnd

Затем используйте функцию указателя newtype в hsc2hs, чтобы объявить указатель для MyType (т. Е. S0). Затем напишите явную функцию, используя методы доступа hsc2hs для рекурсивного обхода вашей структуры и построения структуры Haskell. На каждом шаге вы проверяете, нажали ли вы нулевой указатель, и если да, возвращаете MyEnd (или, в зависимости от кодировки данных, просто проверяете, является ли int, указывающий тип в объединении, отрицательным или каким-либо другим), в противном случае переходите к анализу. все, что у вас есть, и если это указатель, продолжайте рекурсивно.

Вы могли бы сделать почти то же самое с hsc2hs.

...