25
Appels de fonctions natives sous C# Proposition d’une architecture pour « wrapper » une classe native

Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Embed Size (px)

Citation preview

Page 1: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Appels de fonctions natives sous C#

Proposition d’une architecture pour « wrapper » une classe native

Page 2: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

• Managed code vs Unmanaged code• C++ (compilation, décoration, exportation)• Fonctionnalités « interops » de .NET• Architecture proposée• Création des 4 projets• Déploiement

Page 3: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Managed Code vs Unmanaged code

• Managed code : code exécuter (interpréter) sous le « framework » .NET.

Page 4: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

• Sous .NET CF 2.0, il n’y a pas de C++/CLI

Managed Code vs Unmanaged code

Page 5: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

C++: Compilation

• Lors de la compilation, le compilateur génère un fichier .obj par fichier .cpp qu’il compile.

• Toutes les fonctions et variables globales compilées dans un fichier .obj sont « marquées ».

• Lors de l’application des liens, le « Linker » génère un fichier « PE » en liant tous les fichiers .obj.

Page 6: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

C++: Décoration• La déclaration d’une fonction dans un fichier .obj

est encodée (décorée).• L’algorithme de décoration dépend du

compilateur (et parfois aussi de sa version).• En C, il n’y a habituellement pas de décoration.

Page 7: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

C++: Décoration

• Exemple: soit la variable globale« int dllVersion ». Son nom décoré sera« ?dllVersion@@3MA » sous Visual C++ 2005

• Pour déclarer, sous C++, une entité non décorée; il faut forcer le compilateur à l’interpréter comme du code C:extern ”C” int dllVersion;

Page 8: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

C++: Exportation

• Pour exporter une variable globale ou fonction, sa déclaration doit être ajoutée dans la table d’exportation du fichier « PE ».

• « __declspec(dllexport) » le fait automatiquement.

Page 9: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

C++: Exportation

Page 10: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

C++: Exportation

• Pour exporter une fonction non décorée:extern “C” __declspec(dllexport) void fnt(int);

Page 11: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Fonctionnalités « Interops » de .NET

• P/invoke permet, sous .NET, d’exécuter du code natif (unmanaged).

• Sous CF 2.0, la convention d’appel est __cdecl

[DllImport("CommandCInterface.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, EntryPoint = "SetNameAgeCommand_SetNameAgeCommand_name_age")] internal static extern IntPtr SetNameAgeCommand_SetNameAgeCommand_name_age(byte[] name, Int32 age);

Page 12: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Architecture proposée : buts

• Pouvoir simplement importer une classe sous C# qui fut implémentée sous C++ (unmanaged).

• Apporter très peu de modifications au projet à importer.

• Compréhensible et possiblement automatisable.

• Simple à déployer.

Page 13: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Architecture proposée : ModèleUnmanaged Code

CommandCInterface.dll Command.dll

Command.h Command.cpp

CommandCInterface.cpp

API.h

CommandCInterface.h

Managed Code

DeviceApp.exe CommandCSInterface.dll

Program.csCommandCSInterface.cs

Page 14: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Architecture proposée: projet « Command.dll »

• Est un projet C++ unmanaged code.• Est le projet original à importer sous .NET• Nécessite très peu (ou pas du tout de

modification).

Page 15: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Architecture proposée: CommandCInterface.dll

• Est un projet C++ unmanaged code.• Est une interface C de la classe Command.• Pour chaque fonction membre de la classe

« Command », il faut exporter une fonction « wrapper »

• Il faut ajouter une référence au projet Command.dll• Exemple:

extern "C" __declspec(dllexport) void SetNameAgeCommand_EncodeCommand(SetNameAgeCommand *this_);

Page 16: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Architecture proposée: CommandCSInterface.dll

• Est un projet C#.• Est une interface C# de la classe Command.• Pour chacune des fonctions exportées de

CommandCInterface.dll, il faut ajouter une fonction statique de type p/invoke.

• Il faut ajouter une dépendance au projet CommandCInterface.dll.

Page 17: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Architecture proposée: CommandCSInterface.dll

• La classe interface doit encapsuler un pointeur « protected IntPtr this_; » sur l’objet « Command ». Il doit être passé en paramètre lors de l’appel d’une fonction.

• « this_ » est initialisé lors de la création d’une instance.

• « this_ » est détruit lors de la destruction de l’instance.

Page 18: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Architecture proposée: CommandCSInterface.dll

[DllImport("CommandCInterface.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, EntryPoint = "SetNameAgeCommand_EncodeCommand")] private static extern void SetNameAgeCommand_EncodeCommand(IntPtr p);

Page 19: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Architecture proposée: DeviceApp.exe

• Est un projet C#• Utilise l’interface C# pour accéder à un objet

de type « Command ».• Il faut ajouter une référence au projet

CommandCSInterface.dll.

Page 20: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Création du projet Command.dll

• C++, librairie pour Windows Mobile Device 5.0.

• Réutiliser les mêmes fichiers utilisés pour compiler le projet sous Win32.

• S’assurer d’être en « Unicode ».

Page 21: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Création du projet: CommandCInterface.dll

• C++, librairie pour Windows Mobile Device 5.0.

• S’assurer d’être en « Unicode ».• Ne pas oublier la référence sur Command.dll

Page 22: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Création du projet: CommandCSInterface.dll

• C#, librairie 2.0 pour Windows Mobile Device 5.0.

• Ne pas oublier la dépendance sur CommandCInterface.dll.

Page 23: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Création du projet: DeviceApp.exe

• C# application graphique 2.0 pour Windows Mobile Device 5.0.

• Ne pas oublier la référence sur CommandCSInterface.dll.

Page 24: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Déploiement

• Il est important d’ajuster les propriétés des 4 projets concernant leur déploiement.

• Tous les projets doivent être déployés dans le même répertoire!

Page 25: Appels de fonctions natives sous C# Proposition dune architecture pour « wrapper » une classe native

Questions…