/// <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 ); } }