Question

initializers du module sont une caractéristique du CLR qui ne sont pas directement disponibles en C # ou VB.NET. Ce sont des méthodes statiques nommés globaux .cctor qui sont garantis à courir avant tout autre code (initializers type, constructeurs statiques) dans un assemblage sont exécutés. Je voulais récemment l'utiliser dans un projet et piraté mon propre ensemble solution (tâche de programme de console / msbuild) utilisant Mono.Cecil, mais je me demandais:

  1. Est-il possible de tromper le compilateur C # en émettant intializers module? Tous les attributs (par exemple CompilerGenerated, SpecialName) ou une autre supercherie qui pourraient être utilisés?

  2. Faites le C # / VB.NET émette jamais ces initializers eux-mêmes dans un but? D'après ce que j'ai vu, ils sont utilisés par C ++ géré à certaines fins Interop, mais je ne pouvais trouver aucune référence à ce qu'ils soient utilisés à d'autres fins. Toutes les idées?

Était-ce utile?

La solution

Non, il n'y a aucun moyen de les émettre en C #, parce que C # met tout dans une initializers classe / struct et modules doivent être globale.

Vous devrez utiliser un autre outil pour les écrire, de préférence IL-Assembleur.

En ce qui concerne la deuxième question, je dois admettre que je ne sais pas, mais je ne l'ai jamais vu aucun généré par C #, et j'utilise ildasm assez souvent, donc je suppose qu'il ne les émet pas.

Autres conseils

Consultez le addon module initialiseur de l'impressionnant projet opensource IL-Weaver " fody ", écrit par Simon Cropp: https://github.com/fody/moduleinit

Il vous permet de spécifier une méthode qui sera traduit en un initialiseur d'assemblage par fody:

public static class ModuleInitializer
{
    public static void Initialize()
    {
        //Init code
    }
}

obtient ceci:

static <Module>()
{
    ModuleInitializer.Initialize();
}

Peut-être namespace System.Reflection.Emit peut vous aider. énumération MethodAttributes contient des éléments similaires (SpecialName, RTSpecialName).

Einar, Votre question n'a pas fait clair pour moi que vous avez déjà écrit un outil qui permet d'injecter un initialiseur de module dans une assemblée déjà compilé.

http://einaregilsson.com/module-initializers-in-csharp

J'ai essayé votre application et il fonctionne parfaitement. Comme vous écrivez cela devrait fonctionner avec tous les cadres actuels de 2 à 4,5.

Il n'y a qu'un seul problème qui rend votre solution inutile pour moi: Votre initializer est appelée lorsque l'application accède d'abord à quoi que ce soit dans l'assemblée.

Ce que je dois est que le module initialiseur doit être appelé immédiatement lorsque l'Assemblée est chargé dans le processus. Mais ce n'est pas. Donc, si l'application n'a pas accès à l'ensemble il ne sera jamais initialisé.

Après moi enquête sur une journée entière, il paraît que la seule façon d'y arriver est d'écrire une Managed Assemblée C ++ et exécuter le code dans DllMain ().

Si vous avez des constructeurs statiques ou des classes singleton que vous pouvez accéder à un véritable compilateur variable statique C # émettra .cctor.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top