@@ -93,7 +93,6 @@ internal static Version PyVersion
93
93
}
94
94
}
95
95
96
-
97
96
/// <summary>
98
97
/// Initialize the runtime...
99
98
/// </summary>
@@ -113,7 +112,10 @@ internal static void Initialize(bool initSigs = false, ShutdownMode mode = Shutd
113
112
}
114
113
ShutdownMode = mode ;
115
114
116
- if ( Py_IsInitialized ( ) == 0 )
115
+ bool interpreterAlreadyInitialized = TryUsingDll (
116
+ ( ) => Py_IsInitialized ( ) != 0
117
+ ) ;
118
+ if ( ! interpreterAlreadyInitialized )
117
119
{
118
120
Py_InitializeEx ( initSigs ? 1 : 0 ) ;
119
121
if ( PyEval_ThreadsInitialized ( ) == 0 )
@@ -787,6 +789,34 @@ internal static unsafe long Refcount(IntPtr op)
787
789
return * p ;
788
790
}
789
791
792
+ /// <summary>
793
+ /// Call specified function, and handle PythonDLL-related failures.
794
+ /// </summary>
795
+ internal static T TryUsingDll< T > ( Func < T > op )
796
+ {
797
+ try
798
+ {
799
+ return op ( ) ;
800
+ }
801
+ catch ( TypeInitializationException loadFailure )
802
+ {
803
+ var delegatesLoadFailure = loadFailure ;
804
+ // failure to load Delegates type might have been the cause
805
+ // of failure to load some higher-level type
806
+ while ( delegatesLoadFailure . InnerException is TypeInitializationException nested)
807
+ {
808
+ delegatesLoadFailure = nested ;
809
+ }
810
+
811
+ if ( delegatesLoadFailure . InnerException is BadPythonDllException badDll)
812
+ {
813
+ throw badDll ;
814
+ }
815
+
816
+ throw ;
817
+ }
818
+ }
819
+
790
820
/// <summary>
791
821
/// Export of Macro Py_XIncRef. Use XIncref instead.
792
822
/// Limit this function usage for Testing and Py_Debug builds
@@ -2270,10 +2300,6 @@ internal static void SetNoSiteFlag()
2270
2300
if ( _PythonDll != "__Internal" )
2271
2301
{
2272
2302
dllLocal = loader . Load ( _PythonDll ) ;
2273
- if ( dllLocal == IntPtr . Zero )
2274
- {
2275
- throw new Exception ( $ "Cannot load { _PythonDll } ") ;
2276
- }
2277
2303
}
2278
2304
try
2279
2305
{
@@ -2617,8 +2643,8 @@ static Delegates()
2617
2643
}
2618
2644
catch ( MissingMethodException e ) when ( libraryHandle == IntPtr . Zero )
2619
2645
{
2620
- throw new MissingMethodException (
2621
- "Did you forget to set Runtime.PythonDLL? " +
2646
+ throw new BadPythonDllException (
2647
+ "Runtime.PythonDLL was not set or does not point to a supported Python runtime DLL. " +
2622
2648
" See https://github.com/pythonnet/pythonnet#embedding-python-in-net" ,
2623
2649
e ) ;
2624
2650
}
@@ -2889,6 +2915,12 @@ static Delegates()
2889
2915
}
2890
2916
}
2891
2917
2918
+ internal class BadPythonDllException : MissingMethodException
2919
+ {
2920
+ public BadPythonDllException ( string message, Exception innerException)
2921
+ : base ( message , innerException ) { }
2922
+ }
2923
+
2892
2924
2893
2925
public enum ShutdownMode
2894
2926
{
0 commit comments