One of my customers encountered a problem today that doesn't appear with .NET Framework/Mono.
For some reason in this function (ENet.cs line 747):
[DllImport(nativeLibrary, CallingConvention = CallingConvention.Cdecl)]
internal static extern Address enet_peer_get_address(IntPtr peer);
marshaling is not possible of an ENetAddress struct (ENet.cs line 64) which internally contained in Address (ENet.cs line 90):
[StructLayout(LayoutKind.Sequential)]
public struct ENetAddress {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] host;
public ushort port;
}
look at Peer.Address (ENet.cs line 515).
The runtime throws this exception:
Unhandled Exception: System.Runtime.InteropServices.MarshalDirectiveException: Method's type signature is not PInvoke compatible.
at ENet.Native.enet_peer_get_address(IntPtr peer)
at ENet.Peer.get_Address() in E:TestENetServerENet.cs:line 517
at TestENetServer.Program.Main(String[] args) in E:TestENetServerProgram.cs:line 25
Here's an example of projects - ENetCSharpTest.zip
Simple run the server and then the client, and you will catch an exception.
Here's repository with a complete source code including the native library - https://github.com/nxrighthere/ENet-CSharp
cc @luqunl
As a workaround, I changed the functions to obtain an address directly from the unmanaged side, instead of marshaling a struct.
cc @AaronRobinsonMSFT (wrt marshalling test coverage)
@jkoritzinsky Didn't you add some testing for this scenario?
I thought I did. I'll go check.
Fixed by dotnet/coreclr#21470
Sorry for the late reply: I just add as an information for other people stumbling in similar cases that the change in dotnet/coreclr#21470 is only available in recent .NET core runtimes (unfortunately the improvement has not been backported in .NET framework so far) and it also allows marshaling of structures like the following as return values:
[StructLayout(LayoutKind.Sequential)]
struct PString
{
[MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 1)]
public string String;
public int Lenght;
}
unfortunately the improvement has not been backported in .NET framework so far
I want to set expectations here with respect to the above. There are no plans (now or in the future) to port any new interop work to .NET Framework.
I want to set expectations here with respect to the above. There are no plans (now
or in the future) to port any new interop work to .NET Framework.
Perfectly understandable to me. Thank you very much for the clarification.
Most helpful comment
Fixed by dotnet/coreclr#21470