/// <summary>
        /// Bind entry points from native library for static delegates of class 'Type' and
        /// he's instances
        /// </summary>
        /// <param name="type">
        /// Type of static class
        /// </param>
        /// <param name="loadedLibrary">loaded library, from which taken entry points</param>
        public static void BindMethods(
            Type type,
            ILoadedLibrary loadedLibrary
            )
        {
            // initialize delegates
            var delegates = type.GetProperties(BindingFlags.Public | BindingFlags.Static).Where(
                x =>
                (x.PropertyType.BaseType == typeof(MulticastDelegate) ||
                 x.PropertyType.BaseType == typeof(Delegate))
                );

            foreach (var delegateProp in delegates)
            {
                var entryName = delegateProp.PropertyType.Name;

                var entryPtr = loadedLibrary.GetFunctionAdress(entryName);
                var method   = Marshal.GetDelegateForFunctionPointer(entryPtr, delegateProp.PropertyType);
                delegateProp.SetValue(null, method);
            }

            // recursive initializing of nested clasess (types), which is a present C++ scope
            var nestedClasses = type.GetNestedTypes().Where(x => !_reservedNestedTypes.Contains(x.Name));

            foreach (var nestedType in nestedClasses)
            {
                BindMethods(nestedType, loadedLibrary);
            }

            // recursive initializing of instances, whose types is a present C++ scope
            var instanceProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Static).Where(
                x =>
                x.PropertyType != typeof(LibraryPack) &&
                x.PropertyType.BaseType != typeof(Delegate) &&
                x.PropertyType.BaseType != typeof(MulticastDelegate)
                );

            foreach (var instanceProperty in instanceProperties)
            {
                var scopeOb = Activator.CreateInstance(instanceProperty.PropertyType);
                instanceProperty.SetValue(null, scopeOb);
                BindMethods(
                    scopeOb,
                    loadedLibrary
                    );
            }
        }
        public static void BindMethods(
            object scopeObject,
            ILoadedLibrary loadedLibrary
            )
        {
            var scopeType = scopeObject.GetType();

            // initialize delegates
            var delegateProps = scopeType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(
                x =>
                (x.PropertyType.BaseType == typeof(MulticastDelegate) ||
                 x.PropertyType.BaseType == typeof(Delegate))
                );

            foreach (var delegateProp in delegateProps)
            {
                var entryName = delegateProp.PropertyType.Name;
                var entryPtr  = loadedLibrary.GetFunctionAdress(entryName);
                var method    = Marshal.GetDelegateForFunctionPointer(entryPtr, delegateProp.PropertyType);
                delegateProp.SetValue(scopeObject, method);
            }

            // recursive initializing of instances, whose types is a present C++ scope
            var instanceProperties = scopeType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(
                x =>
                x.PropertyType != typeof(LibraryPack) &&
                x.PropertyType.BaseType != typeof(Delegate) &&
                x.PropertyType.BaseType != typeof(MulticastDelegate)
                );

            foreach (var instanceProperty in instanceProperties)
            {
                var scopeOb = Activator.CreateInstance(instanceProperty.PropertyType);
                instanceProperty.SetValue(scopeObject, scopeOb);
                BindMethods(
                    scopeOb,
                    loadedLibrary
                    );
            }
        }
        /// <summary>
        /// Bind entry points from native library for static delegates of class 'Type'
        /// </summary>
        /// <param name="type">
        /// Type of static class, representation native lib or C++ scope.
        /// </param>
        /// <param name="parentTypes">
        /// enumeration of parent types of this C++ scope like "parent1::parent2::type",
        /// if parentTypes == null, this type evaluated as native lib (no scope)
        /// </param>
        /// <param name="loadedLibrary">loaded library, from which taken entry points</param>
        /// <param name="entryPoints">enumeration of demangled entry points</param>
        public static void BindMethodsWithScope(
            Type type,
            IEnumerable <Type> parentTypes,
            ILoadedLibrary loadedLibrary,
            IEnumerable <FunctionEntryName> entryPoints
            )
        {
            // concat entry name like "foo::bar::static_class:getBar"
            var resultParentName = "";

            if (parentTypes != null)
            {
                foreach (var parentType in parentTypes)
                {
                    resultParentName += $"{parentType.Name}::";
                }
                resultParentName += $"{type.Name}::";

                var newParentTypes = parentTypes.ToList();
                newParentTypes.Add(type);
                parentTypes = newParentTypes;
            }
            else
            {
                parentTypes = new List <Type>();
            }

            // initialize delegates
            var delegates = type.GetProperties(BindingFlags.Public | BindingFlags.Static).Where(
                x =>
                (x.PropertyType.BaseType == typeof(MulticastDelegate) ||
                 x.PropertyType.BaseType == typeof(Delegate))
                );

            foreach (var delegateProp in delegates)
            {
                var entryName = $"{resultParentName}{delegateProp.PropertyType.Name}";

                var findEntryPoints       = entryPoints.Where(x => x.DemangledName == entryName);
                var findEntryPointsLength = findEntryPoints.Count();

                if (findEntryPointsLength >= 2)
                {
                    var stringBuilder = new StringBuilder();
                    stringBuilder.Append("Not implement bind build for situation");
                    stringBuilder.Append(", when find more two entry points with identical names:\n");
                    foreach (var findEntryPoint in findEntryPoints)
                    {
                        stringBuilder.Append($"{findEntryPoint.DemangledSignature}\n");
                    }
                    throw new NotImplementedException(stringBuilder.ToString());
                }
                else if (findEntryPointsLength == 0)
                {
                    throw new Exception($"Not find entry point for name:{entryName}");
                }

                var entryPtr = loadedLibrary.GetFunctionAdress(findEntryPoints.First().MangledName);
                var method   = Marshal.GetDelegateForFunctionPointer(entryPtr, delegateProp.PropertyType);
                delegateProp.SetValue(null, method);
            }

            // recursive initializing of nested clasess (types), which is a present C++ scope
            var nestedClasses = type.GetNestedTypes().Where(x => !_reservedNestedTypes.Contains(x.Name));

            foreach (var nestedType in nestedClasses)
            {
                BindMethodsWithScope(
                    nestedType,
                    parentTypes,
                    loadedLibrary,
                    entryPoints);
            }

            // recursive initializing of instances, whose types is a present C++ scope
            var instanceProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Static).Where(
                x =>
                x.PropertyType != typeof(LibraryPack) &&
                x.PropertyType.BaseType != typeof(Delegate) &&
                x.PropertyType.BaseType != typeof(MulticastDelegate)
                );

            foreach (var instanceProperty in instanceProperties)
            {
                var scopeOb = Activator.CreateInstance(instanceProperty.PropertyType);
                instanceProperty.SetValue(null, scopeOb);
                BindMethodsWithScope(
                    scopeOb,
                    parentTypes,
                    loadedLibrary,
                    entryPoints
                    );
            }
        }
예제 #4
0
 public void AddLibrary(ILoadedLibrary library)
 {
     _loadedLibraries.Add(library);
 }