LINUX.ORG.RU

c2hs и struct по значению

 c2hs, , ,


1

2

Мне кажется, или c2hs вообще не может в функции, где параметр-структура передаётся по значению?

test.h:

typedef struct
{
  int bar;
} Foo;

void foo(Foo);

test.chs:

#include "test.h"
{#call foo#}
Результат:
[ERROR]  >>> Illegal structure or union type!
  There is not automatic support for marshaling of structures and  unions;

Если передавать по указателю, всё нормально. Сишную обёртку, которая преобразует вызов по значению в вызов по указателю, я, конечно, могу написать, но как правильно-то?



Последнее исправление: dmfd (всего исправлений: 2)

There is not automatic support for marshaling of structures and unions;

маршалинг для струкруры написал сам?

qnikst ★★★★★
()
Ответ на: комментарий от dmfd

Но даже с маршаллером c2hs выдаёт ту же ошибку.

dmfd
() автор топика
Ответ на: комментарий от dmfd

так не нашёл у себя подходящих примеров, а с наскоку сделать не смог, ты бы написал в их рассылку, а если решишь проблему то сюда отписался :)

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

В haskell-cafe что ли? Я там не прописан. Если к вечеру ответ не найду, попробую там спросить.

dmfd
() автор топика

http://haskell.1045720.n5.nabble.com/Could-FFI-support-pass-by-value-of-struc... http://stackoverflow.com/questions/10903940/haskell-ffi-how-to-handle-c-funct...

Короче говоря, тут дело не в c2hs, а в самом GHC FFI и C ABI. С помощью хаков разной степени загрязненности можно сделать нечто не кроссплатформенное, но стандартного способа нѣтъ. Такие дела.

dmfd
() автор топика

Bump.

Во-первых, уже после того, как я со стенаниями сляпал полуавтоматический генератор chs файлов, я где-то вычитал упоминание, что, мол, c2hs скриптабельный сам по себе. Но больше в интернетах подтверждений тому не нашлось. Подтвердят или опровергнут это местные эксперты?

Пункт 2. В связи с печальным ответом на заглавный вопрос, встала проблема с кучей вызовов с передачей структур по значениям. Говорят, hsc2hs устроен по-другому, он генерирует сишные файлы. Может в нём данная проблема обойдена? Что-то по нему информации совсем уж исчезающе мало.

dmfd
() автор топика
Ответ на: комментарий от dmfd

я где-то вычитал упоминание, что, мол, c2hs скриптабельный сам по себе

Если считать

#include "test.h"

{# pointer *Foo as FooPtr -> Foo #}

data Foo = ...

instance Storable Foo where ...

#c
int my_foo(Foo *s) { return foo(*s); }
#endc

withFoo :: Foo -> (FooPtr -> IO a) -> IO a
withFoo = with

{# fun my_foo as foo { withFoo * `Foo' } -> `Int' fromIntegral #}

в *.chs файле с последующим mv *.chs.h -> *.chs.c для передачи *.chs.c в ghc --make. Всё равно руками приходится делать.

Говорят, hsc2hs устроен по-другому, он генерирует сишные файлы. Может в нём данная проблема обойдена?

Насколько я видел при использовании hsc2hs foreign import пишут руками, но может не всё видел.

Ещё можно на libffi посмотреть — общелисповая cffi реализует передачу и возврат структур по значению с её помощью (у реализаций CL с этим тоже проблемы).

quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 1)
Ответ на: комментарий от quasimoto

Про libffi почитаю подробнее, в описнии упоминалось некое fsbv, которое как раз то, что нужно, и даёт. GHC его вроде как раз и использует?

#c
int my_foo(Foo *s) { return foo(*s); }
#endc

Примерно так и делаю, но в chs только объявления функций, а реализация в отдельном сишном файле.

Если считать...

Я немного о другом говорил. Мой велосипед умеет разбирать сишные заголовки и, если экспортированная функция удовлетворяет каким-то заданным условиям, printf-ом делает заготовку chs файла. Можно матчить параметры по типу и имени, добавляя маршаллинг по желанию. Такого функционала ни в c2hs, ни в hsc2hs, как я понял, нет.

Был ещё некий cgen, но я его ни разу не смог заставить хотя бы распарсить хидер.

dmfd
() автор топика
Ответ на: комментарий от dmfd

мне показалось что сишный wrapper это самое адекватное решение, при поверхностном просмотре api libffi нужного тебе не нашел.

есть прикольный парсер gccxml:

https://bitbucket.org/Shimuuar/gccxml

я использовал - мне понравилось, но до того, чтобы написать полноценный генератор байндингов руки не дошли.

Ещё есть Language.C, если у тебя чистый си то им даже проще будет, мне то нужно было к плюсам без export C линковаться и я сишный врапперы делал.

qnikst ★★★★★
()
Последнее исправление: qnikst (всего исправлений: 1)
Ответ на: комментарий от qnikst

мне показалось что сишный wrapper это самое адекватное решение

Там сплошной boilerplate из разыменований/memcpy.

Ещё есть Language.C

Я им и пользовался.

есть прикольный парсер gccxml

Спасибо, гляну.

dmfd
() автор топика
Ответ на: комментарий от dmfd

в описнии упоминалось некое fsbv

Это Foreign Structure By Value — библиотека для CL которая теперь включена в CFFI.

GHC его вроде как раз и использует?

libffi? Да.

Мой велосипед умеет разбирать сишные заголовки и, если экспортированная функция удовлетворяет каким-то заданным условиям, printf-ом делает заготовку chs файла

А ты каким парсером разбираешь? Есть language-c — он умеет достаточно подробно разбирать, так что можно отделить декларации функций со структурами по значению и по указателям (придётся строить граф typedef-ов и окружение с информацией про имена, естественно), так что на основании этого можно написать автоматических обёрток для функций со структурами по значению.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

А ты каким парсером разбираешь? Есть language-c

Вот им как раз.

так что на основании этого можно написать автоматических обёрток для функций со структурами по значению.

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

dmfd
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.