Список классов и заголовков функций из библиотеки C# - PullRequest
1 голос
/ 02 апреля 2020

У меня есть сторонняя библиотека C# DLL (которая обфусцирована), и я хочу обернуть ее в python, используя pytho nnet.

Пока что я смог сделать то, что я хочу, проверив содержимое DLL в Visual Studio 2017 и вручную написав функцию-обертку по функциям, и их сотни. Я не вижу способа перечисления в текстовом файле или копирования того, что я вижу в проводнике VS dll, в текстовый файл для автоматизации задачи переноса.

Есть ли способ вывести содержимое списка. NET (C#) DLL файл в текст?

1 Ответ

1 голос
/ 02 апреля 2020

Вы можете попробовать это.

Используя рефлексию и CodeDom, эта реализация пытается создать исходный код пустого тела для всех типов, их свойств и методов в данной сборке.

Просто передайте PrintOutAssembly ссылку на сборку запутанной библиотеки.

Надеюсь, это поможет.

private static void PrintOutMethod(CodeTypeDeclaration codeTypeDeclaration, MethodInfo method)
{
    if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))
    {
        return;
    }

    CodeMemberMethod codeMethod;

    codeTypeDeclaration.Members.Add
    (
        codeMethod = new CodeMemberMethod()
        {
            Name = method.Name,
            ReturnType = new CodeTypeReference(method.ReturnType),
            Attributes =
                (MemberAttributes.Public) |
                (method.IsFinal ? MemberAttributes.Final : MemberAttributes.Public) |
                (method.IsAbstract ? MemberAttributes.Abstract : MemberAttributes.Public) |
                (method.GetBaseDefinition() != null ? MemberAttributes.Override : MemberAttributes.Public)
        }
    );

    foreach (ParameterInfo parameter in method.GetParameters())
    {
        codeMethod.Parameters.Add
        (
            new CodeParameterDeclarationExpression()
            {
                Name = parameter.Name,
                Direction = parameter.IsIn && parameter.IsOut ? FieldDirection.Ref : parameter.IsOut ? FieldDirection.Out : FieldDirection.In,
                Type = new CodeTypeReference(parameter.ParameterType)
            }
        );
    }
}

private static void PrintOutProperty(CodeTypeDeclaration codeTypeDeclaration, PropertyInfo property)
{
    codeTypeDeclaration.Members.Add
    (
        new CodeMemberProperty()
        {
            Name = property.Name,
            Type = new CodeTypeReference(property.PropertyType),
            HasGet = property.GetMethod != null,
            HasSet = property.SetMethod != null,
            Attributes =
                (MemberAttributes.Public) |
                (property.GetMethod != null && property.GetMethod.IsFinal ? MemberAttributes.Final : MemberAttributes.Public) |
                (property.SetMethod != null && property.GetMethod.IsFinal ? MemberAttributes.Final : MemberAttributes.Public) |
                (property.GetMethod != null && property.GetMethod.IsAbstract ? MemberAttributes.Abstract : MemberAttributes.Public) |
                (property.SetMethod != null && property.GetMethod.IsAbstract ? MemberAttributes.Abstract : MemberAttributes.Public)
        }
    );
}

static Dictionary<string, CodeNamespace> namespaces = new Dictionary<string, CodeNamespace>();

private static void PrintOutType(System.CodeDom.CodeCompileUnit metaAssembly, CodeTypeDeclaration parentCodeTypeDeclaration, Type type)
{
    CodeNamespace codeNamespace;
    if (!namespaces.ContainsKey(type.Namespace))
    {
        namespaces[type.Namespace] = codeNamespace = new CodeNamespace(type.Namespace);
        metaAssembly.Namespaces.Add(codeNamespace);
    }
    else
    {
        codeNamespace = namespaces[type.Namespace];
    }

    CodeTypeDeclaration codeTypeDeclaration = new CodeTypeDeclaration(type.Name)
    {
        IsClass = type.IsClass,
        IsEnum = type.IsEnum,
        IsInterface = type.IsInterface,
        IsPartial = false,
        IsStruct = type.IsValueType && !type.IsEnum,
        Attributes = MemberAttributes.Public |
            (type.IsAbstract ? MemberAttributes.Abstract : MemberAttributes.Public) |
            (type.IsSealed ? MemberAttributes.Final : MemberAttributes.Public)
    };

    if (type.BaseType != null && type.BaseType != typeof(object))
    {
        codeTypeDeclaration.BaseTypes.Add(type.BaseType);
    }

    foreach (Type interfaceType in type.GetInterfaces())
    {
        codeTypeDeclaration.BaseTypes.Add(interfaceType);
    }

    if (parentCodeTypeDeclaration == null)
    {
        codeNamespace.Types.Add(codeTypeDeclaration);
    }
    else
    {
        parentCodeTypeDeclaration.Members.Add(codeTypeDeclaration);
    }

    foreach (Type nestedType in type.GetNestedTypes())
    {
        if (nestedType.IsPublic)
        {
            PrintOutType(metaAssembly, codeTypeDeclaration, nestedType);
        }
    }

    foreach (PropertyInfo publicProperty in type.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
    {
        PrintOutProperty(codeTypeDeclaration, publicProperty);
    }

    foreach (MethodInfo publicMethod in type.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
    {
        PrintOutMethod(codeTypeDeclaration, publicMethod);
    }
}

private static void PrintOutAssembly(Assembly assembly)
{
    Console.WriteLine("// Meta generation for assembly: {0}", assembly.FullName);

    System.CodeDom.CodeCompileUnit metaAssembly = new System.CodeDom.CodeCompileUnit();

    foreach (Type exportedType in assembly.GetExportedTypes())
    {
        PrintOutType(metaAssembly, null, exportedType);
    }

    System.CodeDom.Compiler.CodeDomProvider.CreateProvider("C#").GenerateCodeFromCompileUnit
    (
        metaAssembly,
        new StreamWriter(Console.OpenStandardOutput()),
        new System.CodeDom.Compiler.CodeGeneratorOptions() { BlankLinesBetweenMembers = true, IndentString = "    ", BracingStyle = "C" }
    );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...