Я пытаюсь использовать SharpPcap в F#, но эта ошибка компилятора блокирует меня на два дня.
Я считаю, что наиболее актуальный ответ: Что такое ошибка «Создание экземпляра типа включает тип по ссылке». и что такое обходной путь в F#, но не подходит для моего контекста.
Пожалуйста, помогите мне обойти это, Спасибо!
open System
open SharpPcap
open SharpPcap.LibPcap
let device = new CaptureFileReaderDevice("test.pcap")
// try workaround 1
let new_package (sender: Object) (e: PacketCapture) = ()
let handler = new PacketArrivalEventHandler(new_package)
device.OnPacketArrival.AddHandler(handler)
// error: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
// try workaround 2
let new_package (e: PacketCapture) = ()
device.OnPacketArrival.Add(new_package)
// error: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
Я думаю, что ошибка в том, что:
public event PacketArrivalEventHandler OnPacketArrival;
public delegate void PacketArrivalEventHandler(object sender, PacketCapture e);
public readonly ref struct PacketCapture
{...}
Делегат PacketArrivalEventHandler
использует PacketCapture
в качестве типа параметра, но это readonly ref struct
, который нельзя использовать для определения функции F# для добавления к событию OnPacketArrival
.
Пожалуйста, помогите мне обойти это, спасибо!
Я хочу передать эту строку компилятору F#:
устройство.OnPacketArrival.Добавить (новый_пакет)
В С# он использовался таким образом:
устройство.OnPacketArrival += новый_пакет
[FS0412] При создании экземпляра типа используется тип по ссылке. Это не разрешено правилами Common IL.
Пожалуйста, прочитайте нижний раздел этой страницы, а затем исправьте свой вопрос, отредактировав его: stackoverflow.com/help/tagged
@Fildor Я хочу исправить эту ошибку компилятора этой строки device.OnPacketArrival.Add(new_package)
Я понял это. Но разрешено ли вам изменять код C# и F# или только одну из сторон?
@Fildor Я понимаю вашу точку зрения, я хочу изменить код F#, а не часть C#. Поскольку я думаю, что этот дизайн пакета C# хорош, проблема заключается в вызове функции C# со стороны F#.
Вы не можете сделать это, используя первоклассные точки прослушивания F# IEvent
, потому что в этом случае тип device.OnPacketArrival
оказывается IEvent<PacketArrivalEventHandler, ref<PacketCapture>>
, чей параметр второго типа ref<PacketCapture>
не разрешен. Об этом сообщает сообщение об ошибке.
Но вы можете использовать базовые методы .NET add_
и remove_
, которые являются аналогами методов свойства get_
и set_
, но для событий. F# позволяет явно вызывать эти «скрытые» методы, даже если они не указаны в списках завершения IDE.
device.add_OnPacketArrival handler
Это работает, потому что он напрямую вызывает метод объекта device
, а не создает значение-оболочку типа IEvent<...>
, а затем вызывает для него .Add
или .AddHandler
.
Кстати, не могли бы вы сказать мне, где я могу получить эти знания: F# allows you to call these "hidden" methods explicitly, even though they're not listed in IDE completion lists.
. Я искал в Google, чтобы попытаться решить мою проблему в течение двух дней, не нашел способа привести меня к этому ответу.
Мои знания об этих методах получены из изучения IL с помощью таких инструментов, как ILSpy и .NET Reflector (когда он был бесплатным), а затем подтверждены экспериментами. Я не знаю каких-либо конкретных мест в Интернете, где обсуждаются эти вещи. Возможно, спецификация C# или IL подойдет? Я почти уверен, что должен.
Какую часть из вышеперечисленного вы можете изменить?