private static GetEngineStructurePtrDelegate ObtainGetEngineStructurePtr(NWEffect Effect)
{
if (GetEngineStructurePtr != null)
return GetEngineStructurePtr;
//
// Traverse the NWNScriptJITIntrinsics wrapper and obtain the
// internal mixed mode NWScriptEngineStructure type. This type
// contains a pointer to the native C++ object chain that may be
// traversed to obtain the underlying CGameEffect.
//
// N.B. Accessing a native pointer type located on a type in a
// non-directly-referenceable assembly cannot be performed
// via conventional language-accessible methods or via
// reflection. Instead, MSIL code must be generated to
// perform the requisite field access and cast to IntPtr.
//
Type NWEngineStructureType = Effect.m_EngineStructure.GetType();
FieldInfo EngineStructurePtrField = NWEngineStructureType.GetField("m_EngineStructure", BindingFlags.Public | BindingFlags.Instance);
DynamicMethod Method = new DynamicMethod("GetEngineStructurePtr", typeof(IntPtr), new Type[] { typeof(object) }, NWEngineStructureType, true);
ILGenerator ILGen = Method.GetILGenerator();
ILGen.Emit(OpCodes.Ldarg_0);
ILGen.Emit(OpCodes.Castclass, NWEngineStructureType);
ILGen.Emit(OpCodes.Ldfld, EngineStructurePtrField);
ILGen.Emit(OpCodes.Ret);
GetEngineStructurePtr = (GetEngineStructurePtrDelegate)Method.CreateDelegate(typeof(GetEngineStructurePtrDelegate));
return GetEngineStructurePtr;
}