11using System ;
2- using System . Diagnostics ;
3- using System . Globalization ;
2+ using System . Collections . Generic ;
43using System . IO ;
5- using System . Reflection ;
64using System . Runtime . InteropServices ;
75using NXPorts . Attributes ;
86
97namespace ClrLoader
108{
119 public static class ClrLoader
1210 {
13- delegate int EntryPoint ( IntPtr buffer , int size ) ;
11+ static bool _initialized = false ;
12+ static List < DomainData > _domains = new List < DomainData > ( ) ;
13+
14+ [ DllExport ( "pyclr_initialize" , CallingConvention . Cdecl ) ]
15+ public static void Initialize ( )
16+ {
17+ if ( ! _initialized )
18+ {
19+ _domains . Add ( new DomainData ( AppDomain . CurrentDomain ) ) ;
20+ _initialized = true ;
21+ }
22+ }
1423
1524 [ DllExport ( "pyclr_create_appdomain" , CallingConvention . Cdecl ) ]
1625 public static IntPtr CreateAppDomain (
@@ -29,11 +38,9 @@ public static IntPtr CreateAppDomain(
2938
3039 Print ( $ "Located domain { domain } ") ;
3140
32- var handle = GCHandle . Alloc ( domain , GCHandleType . Pinned ) ;
33-
34- Print ( $ "Created handle { handle } ") ;
35-
36- return handle . AddrOfPinnedObject ( ) ;
41+ var domainData = new DomainData ( domain ) ;
42+ _domains . Add ( domainData ) ;
43+ return new IntPtr ( _domains . Count - 1 ) ;
3744 }
3845 else
3946 {
@@ -51,18 +58,8 @@ public static IntPtr GetFunction(
5158 {
5259 try
5360 {
54- var domainObj = AppDomain . CurrentDomain ;
55- if ( domain != IntPtr . Zero )
56- {
57- var handle = GCHandle . FromIntPtr ( domain ) ;
58- domainObj = ( AppDomain ) handle . Target ;
59- }
60-
61- var assembly = domainObj . Load ( AssemblyName . GetAssemblyName ( assemblyPath ) ) ;
62- var type = assembly . GetType ( typeName , throwOnError : true ) ;
63- Print ( $ "Loaded type { type } ") ;
64- var deleg = Delegate . CreateDelegate ( typeof ( EntryPoint ) , type , function ) ;
65-
61+ var domainData = _domains [ ( int ) domain ] ;
62+ var deleg = domainData . GetEntryPoint ( assemblyPath , typeName , function ) ;
6663 return Marshal . GetFunctionPointerForDelegate ( deleg ) ;
6764 }
6865 catch ( Exception exc )
@@ -77,21 +74,38 @@ public static void CloseAppDomain(IntPtr domain)
7774 {
7875 if ( domain != IntPtr . Zero )
7976 {
80- var handle = GCHandle . FromIntPtr ( domain ) ;
81- var domainObj = ( AppDomain ) handle . Target ;
82- AppDomain . Unload ( domainObj ) ;
83- handle . Free ( ) ;
77+ try
78+ {
79+ var domainData = _domains [ ( int ) domain ] ;
80+ domainData . Dispose ( ) ;
81+ }
82+ catch ( Exception exc )
83+ {
84+ Print ( $ "Exception in { nameof ( CloseAppDomain ) } : { exc . GetType ( ) . Name } { exc . Message } \n { exc . StackTrace } ") ;
85+ }
86+ }
87+ }
88+
89+ [ DllExport ( "pyclr_finalize" , CallingConvention . Cdecl ) ]
90+ public static void Close ( )
91+ {
92+ foreach ( var domainData in _domains )
93+ {
94+ domainData . Dispose ( ) ;
8495 }
96+
97+ _domains . Clear ( ) ;
98+ _initialized = false ;
8599 }
86100
87- #if DEBUG
88- static void Print ( string s )
101+ #if DEBUG
102+ internal static void Print ( string s )
89103 {
90104 Console . WriteLine ( s ) ;
91105 }
92- #else
93- static void Print ( string s ) { }
94- #endif
106+ #else
107+ internal static void Print ( string s ) { }
108+ #endif
95109 }
96110
97111}
0 commit comments