/// <summary> /// Augments the hosting type constructor with the logic required to initialize the backing pointer field. /// </summary> /// <param name="entrypointName">The name of the entry point.</param> /// <param name="backingFieldType">The type of the backing field.</param> /// <param name="backingField">The backing pointer field.</param> private void AugmentHostingTypeConstructorWithNativeInitialization ( [NotNull] string entrypointName, [NotNull] Type backingFieldType, [NotNull] FieldInfo backingField ) { TargetTypeConstructorIL.EmitLoadArgument(0); TargetTypeConstructorIL.EmitLoadArgument(0); if (Options.HasFlagFast(UseLazyBinding)) { var lambdaBuilder = GenerateSymbolLoadingLambda(entrypointName); GenerateLazyLoadedObject(lambdaBuilder, backingFieldType); } else { var loadPointerMethod = typeof(NativeLibraryBase).GetMethod ( nameof(NativeLibraryBase.LoadSymbol), BindingFlags.NonPublic | BindingFlags.Instance ); TargetTypeConstructorIL.EmitConstantString(entrypointName); TargetTypeConstructorIL.EmitCallDirect(loadPointerMethod); } TargetTypeConstructorIL.EmitSetField(backingField); }
private void AugmentHostingTypeConstructor ( [NotNull] string symbolName, [NotNull] FieldInfo propertyFieldBuilder ) { var loadSymbolMethod = typeof(NativeLibraryBase).GetMethod ( nameof(NativeLibraryBase.LoadSymbol), BindingFlags.NonPublic | BindingFlags.Instance ); TargetTypeConstructorIL.EmitLoadArgument(0); TargetTypeConstructorIL.EmitLoadArgument(0); if (Options.HasFlagFast(UseLazyBinding)) { var lambdaBuilder = GenerateSymbolLoadingLambda(symbolName); GenerateLazyLoadedObject(lambdaBuilder, typeof(IntPtr)); } else { TargetTypeConstructorIL.EmitConstantString(symbolName); TargetTypeConstructorIL.EmitCallDirect(loadSymbolMethod); } TargetTypeConstructorIL.EmitSetField(propertyFieldBuilder); }
private void PropertyInitializationInConstructor ( [NotNull] string symbolName, [NotNull] FieldInfo propertyFieldBuilder ) { var loadSymbolMethod = typeof(NativeLibraryBase).GetMethod ( "LoadSymbol", BindingFlags.NonPublic | BindingFlags.Instance ); TargetTypeConstructorIL.Emit(OpCodes.Ldarg_0); TargetTypeConstructorIL.Emit(OpCodes.Ldarg_0); if (Options.HasFlagFast(UseLazyBinding)) { var lambdaBuilder = GenerateSymbolLoadingLambda(symbolName); GenerateLazyLoadedField(lambdaBuilder, typeof(IntPtr)); } else { TargetTypeConstructorIL.Emit(OpCodes.Ldstr, symbolName); TargetTypeConstructorIL.EmitCall(OpCodes.Call, loadSymbolMethod, null); } TargetTypeConstructorIL.Emit(OpCodes.Stfld, propertyFieldBuilder); }
/// <summary> /// Augments the constructor of the hosting type with initialization logic for this method. /// </summary> /// <param name="entrypointName">The name of the native entry point.</param> /// <param name="delegateBuilderType">The type of the method delegate.</param> /// <param name="delegateField">The delegate field.</param> private void AugmentHostingTypeConstructor ( [NotNull] string entrypointName, [NotNull] Type delegateBuilderType, [NotNull] FieldInfo delegateField ) { var loadFunc = typeof(NativeLibraryBase).GetMethod ( "LoadFunction", BindingFlags.NonPublic | BindingFlags.Instance ).MakeGenericMethod(delegateBuilderType); TargetTypeConstructorIL.Emit(OpCodes.Ldarg_0); // This is for storing field delegate, it needs the "this" reference TargetTypeConstructorIL.Emit(OpCodes.Ldarg_0); if (Options.HasFlagFast(UseLazyBinding)) { var lambdaBuilder = GenerateFunctionLoadingLambda(delegateBuilderType, entrypointName); GenerateLazyLoadedField(lambdaBuilder, delegateBuilderType); } else { TargetTypeConstructorIL.Emit(OpCodes.Ldstr, entrypointName); TargetTypeConstructorIL.EmitCall(OpCodes.Call, loadFunc, null); } TargetTypeConstructorIL.Emit(OpCodes.Stfld, delegateField); }
protected void GenerateLazyLoadedObject([NotNull] MethodBuilder valueFactory, [NotNull] Type type) { var funcType = typeof(Func <>).MakeGenericType(type); var lazyType = typeof(Lazy <>).MakeGenericType(type); var funcConstructor = funcType.GetConstructors().First(); var lazyConstructor = lazyType.GetConstructors().First ( c => c.GetParameters().Any() && c.GetParameters().Length == 1 && c.GetParameters().First().ParameterType == funcType ); // Use the lambda instead of the function directly. TargetTypeConstructorIL.Emit(OpCodes.Ldftn, valueFactory); TargetTypeConstructorIL.Emit(OpCodes.Newobj, funcConstructor); TargetTypeConstructorIL.Emit(OpCodes.Newobj, lazyConstructor); }