2009-05-12 10 views
6

Je dispose d'un vaste code non géré Windows CE 5 C++ qui fournit une interface utilisateur que je souhaite utiliser dans un nouveau produit en le combinant avec une grande quantité de nouvelles entreprises et communications logique écrite en C# géré sur Windows CE 6 et le Compact Framework. L'interface utilisateur peut connaître la logique métier, mais je souhaite que la logique métier ignore l'interface utilisateur pour que je puisse la remplacer ultérieurement par une version gérée ou toute autre interface utilisateur que je choisis comme interface frontale.HOWTO: Appelez l'interface C# managée à partir de C++ non géré sur WindowsCE Compact Framework

J'ai trouvé un article qui décrit comment utiliser COM en tant que pont dans le monde Windows, mais j'ai des difficultés à l'appliquer dans le .NET CF sous WinCE. Dans le passé, j'ai importé des bibliothèques de types et utilisé des appels COM (CoInitialize(), CoCreateInstance()) pour obtenir des pointeurs vers des interfaces sur d'autres plateformes Windows, et c'est la stratégie que je poursuis actuellement: utiliser COM directement dans le bibliothèque C++ non gérée pour accéder aux interfaces C# dans ma bibliothèque gérée, en supposant que la même fonctionnalité est fournie dans WinCE.

Voici mon problème: le typelib. Il n'est pas disponible à partir de ma bibliothèque C# managée comme je l'ai utilisé dans le passé via une instruction "#import" SomeCPPLibrary.dll "'. Je crois qu'il est enterré dans l'assembly .dll, stocké d'une manière différente que par le passé et par conséquent, pas directement disponible via un #import de la bibliothèque elle-même. Je pense que je peux # importer un typelib, mais je ne peux pas trouver un moyen d'extraire le typelib de mon fichier .dll géré, et bien que je puisse être capable de hacher ensemble un fichier de définition d'interface (.idl) et utiliser midl.exe de la plateforme pour générer un fichier .tlb, il n'y a aucune garantie que mon fichier .idl, et par conséquent le fichier .tlb qui en résulte, correspondrait vraiment à ce qui est dans mon C# .dll. Je ne sais même pas si la plate-forme midl.exe fonctionne de cette manière, mais supposons que c'est le cas.

  1. Est-ce que j'aboie le mauvais arbre? Est-il possible d'utiliser une interface C# gérée dans C++ non géré via une interface COM correspondante? Le fait de définir l'attribut [assembly: ComVisible (true)] dans son fichier AssemblyInfo.cs rend toutes les interfaces de l'assembly managé disponibles via COM dans le monde non géré via le GUID défini par AssemblyInfo.cs, ou dois-je faire quelque chose de plus? Comment puis-je faire sortir le typelib du fichier .dll managé afin que ma bibliothèque C++ non managée puisse l'importer?

  2. J'ai essayé d'ajouter mon projet de bibliothèque C# managé comme référence dans le projet de bibliothèque C++ non géré, mais cela n'a pas semblé utile. Une telle référence est-elle pertinente dans cette situation?

  3. Existe-t-il une meilleure approche pour résoudre le problème de base de l'appel du code C# géré à partir du monde C++ non géré? Quelque chose que je viens de lire ici est un libaraire en mode mixte avec une couche de traduction gérée pour combler le fossé non géré/géré. Je ne suis pas sûr que ce soit une bonne stratégie car la vitesse de réponse aux appels est un facteur important, mais pourrait-elle être meilleure à long terme car je prévois de réécrire l'interface utilisateur pour gérer C# à un moment donné? jeter l'interface utilisateur plutôt que de débloquer avec la logique commerciale/communication plus permanente? Indépendamment de la réponse à cette question, je voudrais encore résoudre le problème de l'utilisation de COM, si pour aucune autre raison que la curiosité.

+0

+1 belle écriture –

Répondre

3

J'ai tenté d'appeler C# à partir de C++ dans WinCE. Je ne crois pas qu'il existe un support COM fourni par le Compact Framework, donc vous ne pouvez pas utiliser ComVisible (true).

Je ne pouvais pas non plus trouver un moyen d'héberger .NET en C++ car une fois de plus la fonctionnalité n'était pas exposée dans le Compact Framework.

Ma solution consistait à créer une application C# stub et à communiquer avec l'hôte C++ via Msg Queues. Cela résout également le problème de marshaling de données. La performance pour mon utilisation est bonne. Le plus gros coût est le temps de démarrage du talon que vous auriez à payer de toute façon si vous êtes une application complète était C#.

+0

Cela semble être une excellente façon de le faire. Si le code natif est dans une DLL, je ne pense même pas que vous auriez besoin de files d'attente de messages. le code C# peut appeler des fonctions directement, et vous pouvez passer des délégués/des pointeurs de fonction de C# dans la DLL native pour fournir un moyen d'appeler C# si nécessaire. – tcarvin

2

Vous aboyez le mauvais arbre. Pour que le code natif puisse appeler du code managé, le code natif doit générer le moteur d'exécution du CLR. Ceci est connu comme CLR Hosting, et il n'est pas pris en charge dans les FC. Cela signifie que vous ne pouvez tout simplement pas le faire - même pas avec le piratage créatif (croyez-moi, j'ai essayé toutes les ruelles).

Questions connexes