Static constructors not being called for loaded classes
Raijinili opened this issue · comments
IronPython 2.7.11
Assemblies are in: FFTPatcher_493_Beta_v6.zip
Reproduction code:
from __future__ import print_function
import sys, os
import clr
folder = r'path/to/folder' #Path to the folder with FFTPatcher.exe and PatcherLib.dll.
sys.path.append(os.path.abspath(folder))
clr.AddReference('FFTPatcher.exe', 'PatcherLib.dll', 'PatcherLib.Resources.dll')
from FFTPatcher.Datatypes import FFTPatch
from PatcherLib.Datatypes import Context
psxPatch = FFTPatch()
try:
psxPatch.BuildFromContext(Context.US_PSX)
except SystemError as e:
print(e.clsException.ToString())
Result:
System.TypeInitializationException: The type initializer for 'FFTPatcher.Datatypes.FFTPatch' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at FFTPatcher.Datatypes.FFTPatch.GetAbilityEffects(IList`1 effectBytes, IList`1 itemEffectBytes, IList`1 reactionEffectBytes, Context context)
at FFTPatcher.Datatypes.FFTPatch..cctor()
--- End of inner exception stack trace ---
at FFTPatcher.Datatypes.FFTPatch.GetStandardDefaults(Context context)
at FFTPatcher.Datatypes.FFTPatch.BuildFromContext(Context context)
at Microsoft.Scripting.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run4[T0,T1,T2,T3,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3)
at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
at Microsoft.Scripting.Interpreter.DynamicInstruction`4.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
This is being thrown during initialization of FFTPatch's static variables, such as at:
https://github.com/Glain/FFTPatcher/blob/bd5c402729572d8c90390e881144f868f3be0fe2/Datatypes/FFTPatch.cs#L110
It turns out that the PatcherLib.PSXResources.Binaries.AbilityEffects
(and the others) referenced by this call is null. However, they were supposed to be initialized by the static constructor of PatcherLib.PSXResources
:
https://github.com/Glain/FFTPatcher/blob/bd5c402729572d8c90390e881144f868f3be0fe2/PatcherLib.Resources/PSXResources.cs#L92
I also tried calling the static constructors manually, but this method doesn't show if there are errors in static initialization, so I can't tell why it doesn't work. I assume I'm not calling all of the prerequisite statics correctly.
# Requires Python code from above.
from System import Type
from System.Runtime.CompilerServices.RuntimeHelpers import RunClassConstructor
def runStaticConstructor(cls):
typ = Type.GetType(cls)
return RunClassConstructor(typ.TypeHandle)
from PatcherLib import ResourcesClass, PSXResources, PSPResources
runStaticConstructor(ResourcesClass)
assert ResourcesClass.ZipFileContents
runStaticConstructor(PSXResources)
runStaticConstructor(PSPResources)
runStaticConstructor(PSXResources.Binaries)
runStaticConstructor(PSPResources.Binaries)
print(PSXResources.Binaries.AbilityEffects) #None
print(PSPResources.Binaries.AbilityEffects) #None
I'm not sure it's an IronPython issue here, you can write the same program in C# and you also get the same error...
var psxPatch = new FFTPatch();
psxPatch.BuildFromContext(Context.US_PSX);
System.TypeInitializationException: 'The type initializer for 'FFTPatcher.Datatypes.FFTPatch' threw an exception.'
NullReferenceException: Object reference not set to an instance of an object.
I did that in C# Interactive, but didn't realize it also happened in an actual compiled program.
Do you think it's a problem with the FFTPatcher project?
You're probably missing some initialization steps, for example:
https://github.com/Glain/FFTPatcher/blob/04974a4e28e1a21fd6e181a9b6b3fc23b131bfb1/Program.cs#L42-L52
(Forgot to update.)
Those are to force static initialization. I guess the issue also happens in the original program.
Since then, the static inits have been removed, or at least reduced to the point where I don't have the issue.