Combinaison de C++ et C#
est-ce une bonne idée de combiner C++ et C# ou cela pose-t-il des problèmes immédiats?
j'ai une application qui a besoin de certaines pièces pour être C++, et certaines pièces pour être c# (pour une efficacité accrue). Quelle serait la meilleure façon d'atteindre l'utilisation d'un C++ dll natif en C#?
3 réponses
Oui utiliser C# et C++ pour votre produit est très courant et une bonne idée.
parfois, vous pouvez utiliser managed C++, auquel cas vous pouvez utiliser votre module managed C++ comme n'importe quel autre module .NET.
Typiquement, vous feriez tout ce que vous pouvez en C#. Pour les pièces que vous devez faire en C++, vous créez typiquement une DLL C++ et puis appelez cette DLL à partir de C#. La formation des paramètres se fait automatiquement pour vous.
Voici un exemple de l'importation d'un C de la fonction à l'intérieur d'une DLL en C#:
[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);
la question est clairement de savoir comment intégrer son propre code C++ à sa solution C#, et pas seulement quel attribut utiliser pour appeler une fonction existante à partir de l'API win32. Même si la réponse était déjà acceptée, je pense qu'elle est incomplète, et la suivante devrait s'appliquer.
Oui, il est pratique courante dans les cas où la tâche peut soit exécuter plus rapidement, utiliser moins de ressources, et aussi dans certains cas pour accéder à des méthodes qui ne sont pas disponibles dans le. Framework.
si votre but est de gagner en efficacité, vous devez coder une bibliothèque C++ non gérée, vous allez créer un nouveau projet C++ non géré (qui se compile comme une bibliothèque dll) dans visual studio et référencer cette bibliothèque à partir de votre projet C#.
dans votre cas, il semble que vous écriviez une bibliothèque C++ non gérée, et ce qui suit s'applique.
Comme pour tout problèmes immédiats que vous posiez des questions sur, cela aurait un impact sur le déploiement et obscurcissement.
déploiement: gardez à L'esprit que le C# DLLs que vous construisez CPU, à la fois 32 et 64 bits, mais cette nouvelle la bibliothèque C++ native et non gérée forcez votre programme à être l'un ou l'autre pour 32 ou 64 spécifique.
C'est quelque chose que vous configurez dans votre gestionnaire de configuration Visual Studio, et seront pris en compte lors de la compilation temps, vous choisirez AnyCPU pour C# et pour votre nouvelle bibliothèque C++ non gérée, qui sera dans son propre projet, vous aurez choisir entre win32 ou x64.
Donc, vous avez maintenant 2 configurations, il est meilleure pratique recommandée des configurations séparées, une pour 32 et un autre pour 64. Ou depuis 32 bits le soutien baisse très rapidement, vous pourrait se concentrer sur 64 bits uniquement.
En outre, votre bibliothèque pourrait finir par faire référence au redistibutable VC++ fourni par Visual Studio, que vous pourriez avoir à inclure dans votre déploiement, bien qu'une certaine version de celui-ci soient inclus sur de nombreux OS, j'ai trouvé c'est rarement le même que j'ai compilé avec et il est préférable de déployer votre application pour en être sûr. Si ce paquet est manquant,la machine cible aura une exception de côté dans le journal d'application eventviewer ->.
pour saisir et gérer une exception lancée à partir d'un code non géré, la seule capture qui fonctionne est celle vide, celle sans exception taper entre parenthèses après la capture(). Donc, vous pouvez envelopper vos appels au code non géré dans ceci pour gérer toutes les exceptions non gérées jeté de l'intérieur du code non géré, si vous mettez un type .net comme catch(Exception), il va juste sauter par-dessus. La seule façon d'attraper une exception non gérée, à l'intérieur du code géré est dans ce format.
try
{
//call unmanaged code
}
catch
{
//handle unmanaged exception
}
- Obfuscation: tous les appels de méthode faits à partir de C# qui appellent maintenant code non managé seront exclus de renommer automatiquement. Et sur le revers de la médaille, si votre bibliothèque C++ non gérée a besoin pour appeler des méthodes de votre gérer assemblées, celles-ci doivent être exclus de renommer manuellement, afin d'être visible à l'appel de la bibliothèque C++ ils.
si ce dont vous avez besoin est seulement d'appeler des bibliothèques C++ bien connues comme celles de Windows, vous n'aurez pas besoin de créer un nouveau projet C++ non géré, utilisez seulement l'attribut [DllImport()] suggéré dans une réponse précédente. Et dans ce cas vous pouvez prendre un coup d'oeil à cette référence http://www.pinvoke.net/
informations supplémentaires sur C# versus c++ différences et possibles problèmes les fusionnant:
- C# est interprété, comme Java. C++ est compilé en binaire natif. Cela comporte plusieurs différences expliquées plus en détail dans les points suivants. Même en utilisant JIT, il nécessite la phase initiale de la traduction.
- compatibilité plate-forme: C#, tel qu'interprété et un produit Microsoft, il fonctionne bien sur Windows, correctement sur Linux grâce à un grand projet
Mono
, mais pas bien (ou pas du tout) sur d'autres plateformes (Android, IOS, autres.) Si vous voulez écrire un logiciel pour un système d'exploitation Embarqué où il n'y a pas de prise en charge d'un système d'exploitation, ou pour écrire un système D'exploitation lui-même, vous ne pouvez généralement pas utiliser C#. C++ est totalement multiplateformes dès que vous avez un compilateur (ce qui est généralement le cas). - le code interprété est habituellement d'un ordre de grandeur plus lent que le code binaire[1]. C'est une raison pour relier C++ dans votre C#.
- Code binaire vs code intermédiaire: Travail de code intermédiaire sur n'importe quel interpréteur disponible sur une architecture spécifique, C++ nécessite une recompilation pour chaque architecture.
- courbe D'apprentissage: afin de combiner les deux langues, les développeurs doivent apprendre plusieurs langues, ce qui augmente le temps d'apprentissage. Il est également plus difficile de trouver des experts dans les deux langues.
- IDE: pour C++, n'importe quel éditeur de texte est suffisant, pour C# vous aurez surtout besoin d'IDE spécifique.
- en temps Réel: Il semble difficile d'imaginer en temps réel conditions avec C#.
- certaines certifications de qualité pourraient être impossibles à obtenir avec C# code (logiciel critique).
Est-ce une bonne idée de les réunir?
Cela dépend probablement de votre projet. Pour le développement de grands HMI sur Windows, cela est susceptible d'améliorer votre temps de développement. Mais d'autres exigences logicielles pourraient vous limiter au c++ seulement.
[1], j'ai lu plusieurs fois que le code interprété est, dans certains cas, même plus rapide que le code binaire, ceci est dû à une idée fausse: L'interpréteur implémente plusieurs fonctions pour plus de commodité, donc quand vous appelez (e.g.)sort(), en réalité il appelle une implémentation binaire de cette fonction. Si cette fonction est bien optimisée, le temps final pourrait être plus rapide, mais juste parce que tous les exécuter en binaire et le composant interprété est minime par rapport à tout le temps requis pour trier. De l'autre côté, si vous codez une logique complète dans les deux langues, la version binaire sera toujours nettement plus rapide. La raison est simple: un interpréteur est un binaire qui exécute, en plus de votre code, tout le cadre de langage.