web-dev-qa-db-fra.com

Générer automatiquement une classe wrapper C # à partir d'une dll dans Visual Studio 2010 Express?

Un de mes collègues m'a dit que Visual Studio permet de pointer sur un .dll et de générer automatiquement une classe d'encapsuleur C #. Est-ce vraiment possible? Et si oui, comment s'y prend-on? J'ai navigué sur le Web, mais je n'ai rien trouvé!

Merci a tous!


Je pensais partager ces ressources aussi,

25
mre

3 cas:

  1. Le DLL représente un assembly géré => que vous référencez directement dans votre projet et utilisez-le
  2. Le DLL représente un objet COM => vous pouvez utiliser l'utilitaire tlbimp.exe pour générer un wrapper géré.
  3. La DLL représente une bibliothèque non gérée avec certaines fonctions exportées. C'est le plus dur. Il n'y a pas d'outils. Vous devrez consulter la documentation de la bibliothèque pour connaître les noms de fonction et les paramètres exportés et pour créer des wrappers P/Invoke gérés. Vous pouvez utiliser l'utilitaire dumpbin.exe pour afficher une liste des fonctions exportées. Voici un article sur MSDN concernant les différentes étapes.
34
Darin Dimitrov

Ce n'est certainement pas possible avec n'importe quelle DLL. Juste un type très spécifique, qui implémente un serveur COM. Le convertisseur a besoin d'une bonne description des types exportés, fournie pour ces serveurs par un bibliothèque de types.

Une bibliothèque de types est l'équivalent exact des métadonnées dans un assembly géré. Bien qu'il commence sa vie en tant que fichier autonome, un fichier .tlb, il est souvent incorporé en tant que ressource dans la DLL. Bon endroit pour cela, garde les descriptions de types proches du code qui les implémente. Tout comme les métadonnées dans un assemblage .NET.

Certains outils avec lesquels on peut jouer pour voir les bibliothèques de types (ne pas savoir si cela fonctionne dans Express): dans Visual Studio, utilisez Fichier + Ouvrir + Fichier et choisissez, par exemple, c:\windows\system32\Shell32.dll. Vous verrez les ressources dans cette DLL, notez le nœud TYPELIB. C'est la bibliothèque de types. C'est binaire, donc la lecture n'est pas pratique. Pour cela, exécutez OleView.exe à partir de l'invite de commandes Visual Studio. Fichier + Afficher Typelib et sélectionnez la même DLL. Cela décompile la bibliothèque de types en IDL, le langage de description d'interface utilisé à l'origine pour créer la bibliothèque de types. Très lisible, vous aurez peu de difficulté à comprendre le langage. Et pouvez facilement voir comment .NET Tlbimp.exe peut traduire cette bibliothèque de types en déclarations C # équivalentes.

Les bibliothèques de types sont anciennes, elles existent depuis 1996. Conçues à l'origine par l'équipe de Visual Basic de Microsoft, elles remplaçaient VBX, le modèle d'extensibilité 16 bits VB. Ils ont réussi très, pratiquement tous les compilateurs Windows les prennent en charge. Mais ils ont un pouvoir expressif limité, il n’ya pas d’appui pour des choses comme les génériques et l’héritage de la mise en œuvre. Il est à noter que l'équipe Windows 8 a remplacé les bibliothèques de types pour WinRT. Ils ont choisi le format de métadonnées .NET.

7
Hans Passant

Je sais que cette question est assez ancienne et qu'elle semble avoir reçu une réponse suffisante, mais je voudrais juste ajouter une pensée qui, à mon avis, pourrait être importante… .. Je pourrais me tromper totalement, alors veuillez prendre ma réponse avec un grain de sel et corriger moi sur ce si je suis.

Pour pouvoir appeler des membres/champs dans une DLL, les informations nécessaires pour les appeler doivent être accessibles sous une forme ou une autre. Cette information devrait être tout ce dont vous avez besoin pour écrire un wrapper. Avec cela, vous pouvez déterminer tous les membres/champs "forme" aka en-têtes de méthode et ainsi de suite.

En C #, il est possible de charger des DLL par réflexion et d’obtenir ces informations. Je ne connais pas les différents types de DLL décrits ci-dessus, mais comme je l'ai dit, pour appeler les membres/champs, ces informations doivent être présentes sous une forme ou une autre. Donc, en utilisant la réflexion pour obtenir cette information, vous pourriez générer une nouvelle classe, par exemple. "prefixOriginalname" et que celui-ci ait les mêmes membres/champs que votre classe d'origine, appelant les membres/champs de votre classe d'origine et ajoutant les fonctionnalités supplémentaires souhaitées.

Alors

  1. Chaque DLL (ou document périphérique) vous donne les informations nécessaires pour utiliser ses types. À savoir tout ce qui est implémenté comme "public"
  2. Vous pouvez accéder à ces informations nécessaires par réflexion
  3. Soit 1. et 2., vous pouvez créer un programme pour extraire les informations nécessaires de DLL et générer des wrappers en conséquence.

Comme je l'ai dit, je ne suis pas sûr à 100% de cette question, car les autres réponses me donnent à penser que cela pourrait être trop difficile, voire impossible, pour une raison quelconque.

0
Smogen