web-dev-qa-db-fra.com

Importer un fichier C ++ .lib et .h dans un projet C #?

Je viens de commencer un projet C # et je souhaite importer un fichier C++ .lib et son fichier d'en-tête (.h) correspondant.

J'ai lu divers articles qui mentionnent tous .dll, plutôt que .lib, ce qui me déroute.

L'image ci-dessous montre les fichiers .lib et .h dont je parle, tout ce que j'ai fait est de les faire glisser dans le projet.

enter image description here

Quelqu'un peut-il m'indiquer une explication plus claire de la façon de procéder? Je suis sûr que ça ne peut pas être aussi dur qu'il n'y paraît.

24
Dan James Palmer

Ce que vous pourriez faire, c'est créer un wrapper C++/CLI et exposer les fonctionnalités de la bibliothèque que vous souhaitez utiliser via votre wrapper. La DLL de wrapper créée que vous pouvez facilement référencer dans votre projet C #. Bien sûr, cela prend un peu de travail pour créer le wrapper géré/non managé, mais sera rentable à long terme.

Pour créer un projet C++ géré, sélectionnez sous les modèles de projet C++ CLR et bibliothèque de classes. Ici, vous pouvez créer un lien vers votre bibliothèque, utilisez le fichier d'en-tête comme vous en avez l'habitude.

Créez ensuite une nouvelle classe (classe ref) et enveloppez-y votre bibliothèque. Un exemple pourrait ressembler à ceci:

LibHeader.h

int foo(...);

Vous écrivez une classe wrapper comme celle-ci: En-tête:

Wrapper.h

public ref class MyWrapper
{
    public:
        int fooWrapped();
};

Votre implémentation:

Wrapper.cpp

#include Libheader.h

int MyWrapper::fooWrapped()
{
     return foo();
}

Espaces de noms et toutes les bonnes choses omises pour plus de simplicité. Vous pouvez désormais utiliser MyWrapper dans votre code C # aussi facilement que n'importe quelle autre classe gérée. Bien sûr, lorsque l'interface de la lib devient plus compliquée, vous devez y penser un peu plus, mais cela peut aider à séparer le lib-code de votre application. J'espère y avoir fait la lumière.

8
S. Larws

Il s'agit malheureusement d'un problème non trivial.

La raison est principalement due au fait que C++ est une langue non gérée. C# est un langage géré. Géré et non géré fait référence à la façon dont une langue gère la mémoire.

  • C++ vous devez faire votre propre gestion de la mémoire (allocation et libération),
  • C# .NET Framework fait la gestion de la mémoire avec un garbage collector .

Dans le code de votre bibliothèque

Vous devez vous assurer que tous les endroits que vous appelez new, devez appeler delete, et il en va de même pour malloc et free si vous utilisez les conventions C.

Vous devrez créer un tas de classes wrapper autour de vos appels de fonction, et assurez-vous que vous ne perdez pas de mémoire dans votre C++ code.

Le problème

Votre principal problème (à ma connaissance) est que vous ne pourrez pas appeler ces fonctions directement dans C# car vous ne pouvez pas lier statiquement du code non managé au code managé .

Vous devrez écrire un .dll pour encapsuler toutes vos fonctions de bibliothèque dans C++. Une fois que vous le faites, vous pouvez utiliser le C# fonctionnalité d'interopérabilité pour appeler ces fonctions à partir de la DLL.

[DllImport("your_functions.dll", CharSet = CharSet.Auto)]
public extern void your_function();
9
Kirk Backus

C'est "aussi difficile qu'il y paraît". C++ et C # sont ambivalents. Le premier a une destruction déterministe, le second non. Maintenant, vous écrivez C++/cli retardant la destruction dans un finaliseur appelé par le garbage collector travaillant dans son propre thread, introduisant des problèmes partout (sécurité des threads, les membres C++ (utilisés dans c ++/cli) sont-ils valides?, ... ). Pire encore, le GC peut suggérer que les objets C++ sont minuscules (un pointeur) et provoquer une sorte de fuite de mémoire (en raison de la délocalisation tardive des petits objets). Essentiellement, vous finissez par écrire un GC au-dessus du GC C++/cli pour supprimer des objets non C++/cli (!) Dans le thread principal ou un autre. Tout ce qui est fou, ...

4
user2249683