2010-05-28 9 views
2

Quelle est la meilleure façon de le faire ....?Conseils sur l'utilisation ou non de la DLL C++ native: PINVOKE & Marshaling?

J'ai du code C++ natif qui utilise beaucoup d'appels Win32 avec des tampons octets (alloués en utilisant HeapAlloc). Je voudrais étendre le code et créer une interface graphique C# ... et peut-être plus tard utiliser une interface graphique Win32 basique (à utiliser là où il n'y a pas de support MFC .Net et limité). (A) Je pourrais juste réécrire le code en C# et utiliser plusieurs PINVOKEs .... mais même avec les PINVOKES dans une classe séparée, le code semble malpropre avec tous les marshaling. Je réécris aussi beaucoup de code. (B) Je pourrais créer une DLL C++ native et utiliser PINVOKE pour marshal dans les structures de données natives. Je suppose que je peux inclure le C++ DLL/LIB natif dans un projet en utilisant C#? (C) Créer une DLL en mode mixte (classe C++ natif plus la classe ref gérée). Je suppose que cela faciliterait l'utilisation de la classe ref gérée en C# ...... mais est-ce le cas? La classe dirigée gérera-t-elle tous les marshaling? Puis-je utiliser cette DLL en mode mixte sur une plate-forme sans .Net (c'est-à-dire accéder au composant non géré C++ natif) ou me limiter aux plates-formes .Net uniquement.

Une chose qui me dérange à propos de chacune de ces options est tout le marshalling. Est-il préférable de créer une structure de données gérée (tableau, chaîne, etc.) et de la transmettre à la classe C++ native, ou inversement?

Des idées sur ce qui serait considéré comme la meilleure pratique ...? Je sais que je peux réécrire le code C++ natif, mais cela signifie dupliquer le code et m'empêche de réutiliser facilement les mises à jour de code avec n'importe quelle application Win32. Ce qui me préoccupe le plus, c'est la meilleure façon de rassembler les différentes données entre le monde géré et non géré. Pour moi, une DLL en mode mixte ressemble à l'option la plus fl exible, mais j'aimerais avoir une perspective différente sur les pièges potentiels.

Répondre

1

Pourquoi ne pas simplement utiliser .NET directement? Il me semble que votre problème provient du fait que vous dépendez de la bibliothèque native d'origine, mais vous ne mentionnez pas qu'il ne peut pas simplement être refait dans .NET. En ce qui concerne l'interopérabilité native .NET, PInvoke est désordonné, mais cela fonctionne. J'irais avec ça si vous ne pouvez pas changer la DLL d'origine en .NET.

0

L'option C vous donne le moins de travail si le marshaling s'avère simple et facile à manipuler (tout est-il blittable?). Il vous donne également un endroit pour accrocher votre propre marshaling. J'ai écrit quelque chose sur ce marshaling il y a des âges entre les types de date etc. mais je pense qu'aujourd'hui j'écrirais une surcharge de marshal_as <> entre vos types contrôlés et natifs. Ce serait la solution la plus élégante et aussi le moins de code.

Mise à jour: trouvé mon ancien article - c'était pour PInvoke. http://codeguru.earthweb.com/columns/kate/article.php/c4867/