From c210e086cd537c7023b469a09df59b48c3800875 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Tue, 1 Mar 2022 12:45:50 +0100 Subject: [PATCH] - .NET API: fix problem with garbage collected delegates for async client control functions (LIB61850-301) --- dotnet/IEC61850forCSharp/Control.cs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/dotnet/IEC61850forCSharp/Control.cs b/dotnet/IEC61850forCSharp/Control.cs index c096c923..b3c2bcc9 100644 --- a/dotnet/IEC61850forCSharp/Control.cs +++ b/dotnet/IEC61850forCSharp/Control.cs @@ -355,6 +355,8 @@ namespace IEC61850 return ControlObjectClient_operate(self, ctlVal.valueReference, operTime); } + private ControlObjectClient_ControlActionHandler internalOperateHandler = null; + private void nativeOperateHandler (UInt32 invokeId, IntPtr parameter, int err, int type, bool success) { GCHandle handle = GCHandle.FromIntPtr(parameter); @@ -487,7 +489,10 @@ namespace IEC61850 GCHandle handle = GCHandle.Alloc(callbackInfo); - UInt32 invokeId = ControlObjectClient_operateAsync(self, out error, ctlVal.valueReference, operTime, nativeOperateHandler, GCHandle.ToIntPtr(handle)); + if (internalOperateHandler == null) + internalOperateHandler = new ControlObjectClient_ControlActionHandler(nativeOperateHandler); + + UInt32 invokeId = ControlObjectClient_operateAsync(self, out error, ctlVal.valueReference, operTime, internalOperateHandler, GCHandle.ToIntPtr(handle)); if (error != 0) { @@ -520,9 +525,12 @@ namespace IEC61850 Tuple callbackInfo = Tuple.Create(handler, parameter); - GCHandle handle = GCHandle.Alloc(callbackInfo); + GCHandle handle = GCHandle.Alloc(callbackInfo); + + if (internalOperateHandler == null) + internalOperateHandler = new ControlObjectClient_ControlActionHandler(nativeOperateHandler); - UInt32 invokeId = ControlObjectClient_selectAsync(self, out error, nativeOperateHandler, GCHandle.ToIntPtr(handle)); + UInt32 invokeId = ControlObjectClient_selectAsync(self, out error, internalOperateHandler, GCHandle.ToIntPtr(handle)); if (error != 0) { @@ -634,7 +642,10 @@ namespace IEC61850 GCHandle handle = GCHandle.Alloc(callbackInfo); - UInt32 invokeId = ControlObjectClient_selectWithValueAsync(self, out error, ctlVal.valueReference, nativeOperateHandler, GCHandle.ToIntPtr(handle)); + if (internalOperateHandler == null) + internalOperateHandler = new ControlObjectClient_ControlActionHandler(nativeOperateHandler); + + UInt32 invokeId = ControlObjectClient_selectWithValueAsync(self, out error, ctlVal.valueReference, internalOperateHandler, GCHandle.ToIntPtr(handle)); if (error != 0) { @@ -669,7 +680,10 @@ namespace IEC61850 GCHandle handle = GCHandle.Alloc(callbackInfo); - UInt32 invokeId = ControlObjectClient_cancelAsync(self, out error, nativeOperateHandler, GCHandle.ToIntPtr(handle)); + if (internalOperateHandler == null) + internalOperateHandler = new ControlObjectClient_ControlActionHandler(nativeOperateHandler); + + UInt32 invokeId = ControlObjectClient_cancelAsync(self, out error, internalOperateHandler, GCHandle.ToIntPtr(handle)); if (error != 0) {