7
votes

Déterminer lorsque .NET est sur le point d'être chargé dans (non géré) C ++

[Ceci devient TLDR ... Désolé ...]

Je travaille sur une application énorme (principalement) C ++ / MFC avec des centaines de DLL; Il prend en charge un mécanisme «Ajout in» téléchargé de manière dynamique via COM, ainsi que des add-ins peuvent être développés dans .NET à l'aide de com Interop. Certaines nouvelles fonctionnalités limitées sont développées dans .NET W / O utilisant ce mécanisme "complément" (bien que toujours chargé de manière dynamique); Cependant, l'utilisateur final peut décider de ne pas utiliser cette fonctionnalité. Ainsi, .NET peut ne pas être chargé au démarrage.

mais, lorsque .NET est chargé , j'ai besoin de faire une initialisation spécifique à la NET (en spécifiquement réglage courriolinulture correspondre à l'interface utilisateur natif / non gérée).

Une solution est simplement un punt et de faire cette initialisation .NET lorsque le code se transforme pour charger soit le nouveau .NET FONCTIONALIY OU COMMENT . Compte tenu de la nature de cette application, il s'agit probablement d'une solution de 95 +% (la plupart des utilisateurs utiliseront la nouvelle fonctionnalité).

mais ce n'est pas infaillible. Quelqu'un pourrait "facilement" ajouter une nouvelle fonctionnalité .NET à tout moment en construisant un module avec le drapeau / clr (rappelez-vous que ceci est une énorme application).

un plus robuste ( La solution évidente) est simplement provoquée .NET à charger au démarrage via C ++ / CLI. Mais certains des développeurs Die-Hard C ++ à qui chaque octet et chaque cycle d'horloge compte ne veulent pas faire cela; Un peu compréhensible car il n'y a pas besoin de définir courant ur / em> sauf si / jusqu'à ce que .net soit chargé.

Une autre possibilité que j'ai pensé à accrocher LoadLibrary mscorlib . Maintenant, je sais que .NET est sur le point d'être chargé pour une raison quelconque, chargez-la de manière normale et faire l'initialisation avant que l'autre code ne fait quoi que ce soit. Mais accrochaing loadlibrary (ou autre chose, à cet égard) n'est vraiment pas quelque chose que je veux faire.

Alors, y a-t-il un moyen facile (IER) / meilleure façon de dire Si .NET sur le point d'être chargé?

Modifier: La réponse de Reed de Lockclversion est assez proche. Le seul HICCUP est qu'il ne fonctionnera pas si vous liez une dll / assemblage à mode mixte. xxx


0 commentaires

5 Réponses :


-1
votes

Vous devriez probablement initialiser la structure .NET au démarrage de l'application. J'ai travaillé sur une application avec un contexte similaire et cela aurait occasionnellement une impasse car 2 DLL essayaient d'initialiser la framework .NET à la Sametime en accédant indirectement à des dlls .NET. Pour résoudre ce problème, nous avons appelé corbindtoruntimeex dans les premières lignes du point d'entrée de l'exécutable.

Je ne pense pas qu'il y ait une façon dont le système d'exploitation vous dira s'il est sur le point de charger .net.


0 commentaires

1
votes

Vous pouvez Exécutez votre propre hôte CLR pour charger des assemblys . Ensuite, vous pouvez prendre des décisions plus spécifiques sur la version de l'exécution (1.1? 2.0? 4.0?) Pour charger et séparer le code géré de votre code, donc Lorsqu'un crash de plug-in, votre code ne va pas tomber avec elle .


0 commentaires

1
votes

Il y a deux choses qui pourraient vous aider: compteurs de performance et WMI. Le CLR .NET s'intègre aux deux, et vous devriez pouvoir interagir avec (WMI serait probablement le mieux) surveiller le démarrage de AppDomain. Cependant, aucun de ces outils n'est particulièrement idéal et en termes de surcharge, ce que Sheng Jiang a suggéré, héberger le CLR seul, serait probablement plus efficace (et donc plus agréable à vos "comptoirs d'octets".)

sur une note légèrement différente ... Si vous avez une mesure d'influence et de contrôle de l'équipe de développement, je règne un peu dans les "compteurs d'octets". L'une des plus grandes idées fausses sur .NET est qu'il est moins efficace que c ++. Cette ancienne erreur doit être enterrée, car .Net peut être incroyablement efficace, et quand il est utilisé correctement, plus efficace que C ++ parfois. Au-delà de l'efficacité de base de l'une ou l'autre plate-forme, vous devez poser la question suivante: combien d'efficacité que je gagnerais vraiment en dépensant des volumes inconnus d'heures optimisant le grain le plus fin, lorsque de statistiquement, ses plus grandes choses qui tuent généralement les performances: des appels croisés ( c.-à-don appelant des objets COM de C ++ par rapport à des objets .NET à partir de .NET), appelez les processus distants (services Web, RPC, etc.), appelant dans une base de données, etc.

Vous pouvez essayer de résoudre votre problème de démarrage .NET AppDomain pour apaiser les idées fausses des compteurs d'octets, ou vous pouvez mettre en œuvre correctement un système .NET et éviter le maréchalage et l'inter-op de frapper qui va devenir massivement plus drainant que toute quantité de réglage de performance au niveau des octets pourrait contrer.


0 commentaires

0
votes

Au lieu d'essayer de se connecter lorsque l'ensemble est chargé, pouvez-vous accrocher lorsque l'appdomain est chargé? Regardez dans System.AppdomainManager pour faire cela.

Après avoir chargé votre système sous-classé.AppdomainManager dans le GAC, il vous suffit de définir des variables d'environnement (AppDomain_Manager_Type, AppDomain_Manager_asm) avant d'exécuter votre programme C ++.


0 commentaires

6
votes

Je pense que vous pouvez le faire en appellant votre processus d'appeler le Lockclversion fonction avant d'utiliser des API gérées. Cette fonction vous permet de spécifier deux Flockclversion Callback Méthodes.

La première méthode ( PBEGINHOSTUPSETUP ) est appelée avant l'initialisation du CLR initialisé la première fois pour le processus d'hébergement. La deuxième méthode ( pendhostetup ) est appelée lorsque l'initialisation du CLR est terminée.

Cela devrait vous permettre de spécifier du code non géré qui fonctionne juste avant et juste après l'initialisation du CLR. Dans votre cas, vous devez probablement accrocher à la pendhostUp pour appeler vos routines de configuration de l'API gérées (vous devez attendre que le CLR soit hébergé avec succès).


1 commentaires

Cela devrait faire exactement ce que vous êtes après - je ne l'ai jamais mis en œuvre, mais j'ai traversé toute l'API d'hébergement de CLR essayant de le suivre.