@@ -72,7 +72,7 @@ private void GenerateDelegate(CppGenerationContext context, GeneratedResult resu
7272 """
7373 ) ) ;
7474
75- // A a C# delegate type that wraps a std::function, and arrange for
75+ // A C# delegate type that wraps a std::function, and arrange for
7676 // the invoke and dispose to be implemented in C++.
7777 CSharpType csType = CSharpType . FromSymbol ( context , item . Type ) ;
7878
@@ -88,7 +88,7 @@ private void GenerateDelegate(CppGenerationContext context, GeneratedResult resu
8888 string disposeCallbackName = $ "{ csType . GetFullyQualifiedNamespace ( ) . Replace ( "." , "_" ) } _{ item . Type . Name } { genericTypeHash } _DisposeCallback";
8989
9090 var invokeParameters = callbackParameters . Select ( p => $ "{ p . CsType . GetFullyQualifiedName ( ) } { p . Name } ") ;
91- var invokeInteropParameters = new [ ] { "IntPtr callbackFunction" } . Concat ( callbackParameters . Select ( p => $ "{ p . CsType . AsInteropTypeParameter ( ) . GetFullyQualifiedName ( ) } { p . Name } ") ) ;
91+ var invokeInteropParameters = new [ ] { "ImplementationHandle callbackFunction" } . Concat ( callbackParameters . Select ( p => $ "{ p . CsType . AsInteropTypeParameter ( ) . GetFullyQualifiedName ( ) } { p . Name } ") ) ;
9292 var callInvokeInteropParameters = new [ ] { "_callbackFunction" } . Concat ( callbackParameters . Select ( p => p . CsType . GetConversionToInteropType ( p . Name ) ) ) ;
9393 var csReturnType = CSharpType . FromSymbol ( context , invokeMethod . ReturnType ) ;
9494
@@ -109,31 +109,34 @@ private void GenerateDelegate(CppGenerationContext context, GeneratedResult resu
109109 $$ """
110110 private class {{ csType . Name }} {{ genericTypeHash }} NativeFunction : System.IDisposable
111111 {
112- private IntPtr _callbackFunction;
113-
114- public {{ csType . Name }} {{ genericTypeHash }} NativeFunction(IntPtr callbackFunction)
112+ internal class ImplementationHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
115113 {
116- _callbackFunction = callbackFunction;
117- }
114+ public ImplementationHandle(IntPtr nativeImplementation) : base(true)
115+ {
116+ SetHandle(nativeImplementation);
117+ }
118118
119- ~{{ csType . Name }} {{ genericTypeHash }} NativeFunction()
120- {
121- Dispose(false);
119+ [System.Runtime.ConstrainedExecution.ReliabilityContract(System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, System.Runtime.ConstrainedExecution.Cer.Success)]
120+ protected override bool ReleaseHandle()
121+ {
122+ {{ disposeCallbackName }} (this.handle);
123+ return true;
124+ }
122125 }
123-
124- public void Dispose()
126+
127+ [System.NonSerialized]
128+ private ImplementationHandle _callbackFunction;
129+
130+ public {{ csType . Name }} {{ genericTypeHash }} NativeFunction(IntPtr callbackFunction)
125131 {
126- Dispose(true);
127- GC.SuppressFinalize(this);
132+ _callbackFunction = new ImplementationHandle(callbackFunction);
128133 }
129134
130- private void Dispose(bool disposing )
135+ public void Dispose()
131136 {
132- if (_callbackFunction != IntPtr.Zero)
133- {
134- {{ disposeCallbackName }} (_callbackFunction);
135- _callbackFunction = IntPtr.Zero;
136- }
137+ if (this._callbackFunction != null && !this._callbackFunction.IsInvalid)
138+ this._callbackFunction.Dispose();
139+ this._callbackFunction = null;
137140 }
138141
139142 public {{ csReturnType . GetFullyQualifiedName ( ) }} Invoke({{ string . Join ( ", " , invokeParameters ) }} )
0 commit comments