Как я использую FFI Haskell на структурах?

Это мои 2 цента на основе ответа Grax , но с двумя параметрами, необходимыми для общего метода.

Предположим, что ваш метод определяется следующим образом в классе Helpers:

public class Helpers
{
    public static U ConvertCsvDataToCollection(string csvData)
    where U : ObservableCollection
    {
      //transform code here
    }
}

В моем случае тип U всегда является наблюдаемым объектом хранения коллекции типа T.

Поскольку у меня есть предопределенные типы, я сначала создаю «фиктивные» объекты, которые представляют наблюдаемый набор (U) и объект, хранящийся в нем (T), и который будет использоваться ниже, чтобы получить их тип при вызове Make

object myCollection = Activator.CreateInstance(collectionType);
object myoObject = Activator.CreateInstance(objectType);

Затем вызовите GetMethod, чтобы найти вашу общую функцию:

MethodInfo method = typeof(Helpers).
GetMethod("ConvertCsvDataToCollection");

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

Вам нужно передать массив Type [] в функцию MakeGenericMethod, которая содержит типы «фиктивных» объектов, которые были созданы выше:

MethodInfo generic = method.MakeGenericMethod(
new Type[] {
   myCollection.GetType(),
   myObject.GetType()
});

Как только это будет сделано, вам нужно вызвать метод Invoke, как указано выше.

generic.Invoke(null, new object[] { csvData });

И все готово.

UPDATE:

Поскольку @Bevan выделен, мне не нужно создавать массив при вызове функции MakeGenericMethod, поскольку он принимает параметры, и мне не нужно создавать объект, чтобы получить типы, поскольку я могу просто передать типы непосредственно этой функции. В моем случае, поскольку у меня есть типы, предопределенные в другом классе, я просто изменил свой код на:

object myCollection = null;

MethodInfo method = typeof(Helpers).
GetMethod("ConvertCsvDataToCollection");

MethodInfo generic = method.MakeGenericMethod(
   myClassInfo.CollectionType,
   myClassInfo.ObjectType
);

myCollection = generic.Invoke(null, new object[] { csvData });

myClassInfo содержит 2 свойства типа Type, которые я установил во время выполнения на основе перечисления значение передается конструктору и предоставит мне соответствующие типы, которые затем я использую в MakeGenericMethod.

Еще раз спасибо за выделение этого @Bevan.

18
задан Daniel O 24 March 2009 в 12:03
поделиться

3 ответа

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

6
ответ дан 30 November 2019 в 09:25
поделиться

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

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

<час>

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

10
ответ дан 30 November 2019 в 09:25
поделиться

Hackage имеет несколько пакетов, которые используют FFI, на который Вы могли посмотреть для примеров.

-3
ответ дан 30 November 2019 в 09:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: