예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #5
0
        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);
        }