I try to use SharpPcap in F#, but I was blocked by this compiler error for two days.
I find the most releate answer is What is the error "A type instantiation involves a byref type." and what is a workaround in F#, but do not fit my context well.
Please help me work around it, Thank you!
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.
I think the error is because:
public event PacketArrivalEventHandler OnPacketArrival;
public delegate void PacketArrivalEventHandler(object sender, PacketCapture e);
public readonly ref struct PacketCapture
{...}
The delegate PacketArrivalEventHandler
use PacketCapture
as param type, but this is a readonly ref struct
which can not use to define F# function to add to Event OnPacketArrival
.
Pls help me workaround it, Thank you!
I want make this line pass the F# compiler:
device.OnPacketArrival.Add(new_package)
In c# it used in this way:
device.OnPacketArrival += new_package
[FS0412] A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
You can't do this by using the F# IEvent
first-class listening points, because in this case the type of device.OnPacketArrival
ends up being IEvent<PacketArrivalEventHandler, ref<PacketCapture>>
, whose second type parameter ref<PacketCapture>
is not allowed. This is what the error message tells you.
But you can use the underlying .NET add_
and remove_
methods, which are analogs of property get_
and set_
methods, but for events. F# allows you to call these "hidden" methods explicitly, even though they're not listed in IDE completion lists.
device.add_OnPacketArrival handler
It works, because it's directly calling a method on the device
object, rather than creating a wrapping value of type IEvent<...>
and then calling .Add
or .AddHandler
on it.