Guide pratique pour créer des wrappers manuellement

Note

Cette aide est spécifique à .NET Framework. Pour l’interopérabilité COM .NET moderne, utilisez l’interopérabilité COM générée par le code source ou l’API System.Runtime.InteropServices.ComWrappers. Pour plus d’informations, consultez la vue d’ensemble de l’interopérabilité COM et la génération de source COM.

Si vous décidez de déclarer manuellement des types COM dans le code source managé, le meilleur endroit pour commencer est d’utiliser un fichier ou une bibliothèque de types idL (Interface Definition Language) existant. Lorsque vous n’avez pas le fichier IDL ou que vous ne pouvez pas générer de fichier de bibliothèque de types, vous pouvez simuler les types COM en créant des déclarations managées et en exportant l’assembly résultant vers une bibliothèque de types.

Simuler des types COM à partir d’une source managée

  1. Déclarez les types dans une langue conforme à la spécification CLS (Common Language Specification) et compilez le fichier.

  2. Exportez l’assembly contenant les types avec l’exportateur de bibliothèque de types (Tlbexp.exe).

  3. Utilisez la bibliothèque de types COM exportée comme base pour déclarer des types managés orientés COM.

Créer un wrapper pouvant être appelé au runtime (RCW)

  1. En supposant que vous disposez d’un fichier IDL ou d’un fichier de bibliothèque de types, déterminez les classes et interfaces que vous souhaitez inclure dans rcW personnalisé. Vous pouvez exclure tous les types que vous n’avez pas l’intention d’utiliser directement ou indirectement dans votre application.

  2. Créez un fichier source dans un langage conforme CLS et déclarez les types. Consultez Résumé de la conversion d’une bibliothèque de types en assembly pour obtenir une description complète du processus de conversion lors de l’importation. En fait, lorsque vous créez un RCW personnalisé, vous effectuez manuellement l’activité de conversion de type fournie par l’importateur de bibliothèque de types (Tlbimp.exe). L’exemple de la section suivante montre les types dans un fichier IDL ou bibliothèque de types et leurs types correspondants dans le code C#.

  3. Une fois les déclarations terminées, compilez le fichier au fur et à mesure que vous compilez tout autre code source managé.

  4. Comme pour les types importés avec Tlbimp.exe, certains nécessitent des informations supplémentaires, que vous pouvez ajouter directement à votre code. Pour plus d’informations, consultez Guide pratique pour modifier les assemblys d’interopérabilité.

Example

Le code suivant montre un exemple de l’interface ISATest et de la classe SATest en IDL, ainsi que les types correspondants en code source C#.

Fichier IDL ou bibliothèque de types

 [
object,
uuid(40A8C65D-2448-447A-B786-64682CBEF133),
dual,
helpstring("ISATest Interface"),
pointer_default(unique)
 ]
interface ISATest : IDispatch
 {
[id(1), helpstring("method InSArray")]
HRESULT InSArray([in] SAFEARRAY(int) *ppsa, [out,retval] int *pSum);
 };
 [
uuid(116CCA1E-7E39-4515-9849-90790DA6431E),
helpstring("SATest Class")
 ]
coclass SATest
 {
  [default] interface ISATest;
 };

Wrapper dans le code source managé

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

[assembly:Guid("E4A992B8-6F5C-442C-96E7-C4778924C753")]
[assembly:ImportedFromTypeLib("SAServerLib")]
namespace SAServer
{
 [ComImport]
 [Guid("40A8C65D-2448-447A-B786-64682CBEF133")]
 [TypeLibType(TypeLibTypeFlags.FLicensed)]
 public interface ISATest
 {
  [DispId(1)]
  //[MethodImpl(MethodImplOptions.InternalCall,
  // MethodCodeType=MethodCodeType.Runtime)]
  int InSArray( [MarshalAs(UnmanagedType.SafeArray,
      SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
 }
 [ComImport]
 [Guid("116CCA1E-7E39-4515-9849-90790DA6431E")]
 [ClassInterface(ClassInterfaceType.None)]
 [TypeLibType(TypeLibTypeFlags.FCanCreate)]
 public class SATest : ISATest
 {
  [DispId(1)]
  [MethodImpl(MethodImplOptions.InternalCall,
  MethodCodeType=MethodCodeType.Runtime)]
  extern int ISATest.InSArray( [MarshalAs(UnmanagedType.SafeArray,
  SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
 }
}

Voir aussi