1
1
using System ;
2
- using System . Diagnostics ;
3
- using System . Globalization ;
2
+ using System . Collections . Generic ;
4
3
using System . IO ;
5
- using System . Reflection ;
6
4
using System . Runtime . InteropServices ;
7
5
using NXPorts . Attributes ;
8
6
9
7
namespace ClrLoader
10
8
{
11
9
public static class ClrLoader
12
10
{
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
+ }
14
23
15
24
[ DllExport ( "pyclr_create_appdomain" , CallingConvention . Cdecl ) ]
16
25
public static IntPtr CreateAppDomain (
@@ -29,11 +38,9 @@ public static IntPtr CreateAppDomain(
29
38
30
39
Print ( $ "Located domain { domain } ") ;
31
40
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 ) ;
37
44
}
38
45
else
39
46
{
@@ -51,18 +58,8 @@ public static IntPtr GetFunction(
51
58
{
52
59
try
53
60
{
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 ) ;
66
63
return Marshal . GetFunctionPointerForDelegate ( deleg ) ;
67
64
}
68
65
catch ( Exception exc )
@@ -77,21 +74,38 @@ public static void CloseAppDomain(IntPtr domain)
77
74
{
78
75
if ( domain != IntPtr . Zero )
79
76
{
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 ( ) ;
84
95
}
96
+
97
+ _domains . Clear ( ) ;
98
+ _initialized = false ;
85
99
}
86
100
87
- #if DEBUG
88
- static void Print ( string s )
101
+ #if DEBUG
102
+ internal static void Print ( string s )
89
103
{
90
104
Console . WriteLine ( s ) ;
91
105
}
92
- #else
93
- static void Print ( string s ) { }
94
- #endif
106
+ #else
107
+ internal static void Print ( string s ) { }
108
+ #endif
95
109
}
96
110
97
111
}
0 commit comments