Procédure : créer manuellement des wrappers
Si vous décidez de déclarer des types COM manuellement dans du code source managé, il est recommandé de démarrer avec un fichier IDL (Interface Definition Language) existant ou une bibliothèque de types existante. Quand vous ne disposez pas du fichier IDL ou ne pouvez pas générer un 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 dans une bibliothèque de types.
Pour simuler des types COM à partir d’une source managée
Déclarez les types dans un langage compatible avec la spécification CLS (Common Language Specification) et compilez le fichier.
Exportez l’assembly contenant les types à l’aide de l’outil Tlbexp.exe (exportateur de bibliothèques de types).
Utilisez la bibliothèque de types COM exportée comme base pour déclarer des types managés orientés COM.
Pour créer un wrapper RCW (Runtime Callable Wrapper)
En supposant que vous disposez d’un fichier IDL ou d’un fichier de bibliothèque de types, choisissez les classes et les interfaces que vous souhaitez inclure dans le wrapper RCW personnalisé. Vous pouvez exclure tous les types que vous ne souhaitez pas utiliser directement ou indirectement dans votre application.
Créez un fichier source dans un langage conforme à la spécification 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 à l’importation. En effet, quand vous créez un wrapper RCW personnalisé, vous effectuez manuellement l’activité de conversion de type fournie par l’outil Tlbimp.exe (importateur de bibliothèques de types). L’exemple fourni dans la section suivante montre les types dans un fichier IDL ou un fichier de bibliothèque de types, et les types correspondants en code C#.
Lorsque les déclarations sont terminées, compilez le fichier comme tout autre code source managé.
Quant aux types importés avec Tlbimp.exe, certains nécessitent des informations supplémentaires, que vous pouvez ajouter directement dans le code. Pour plus d’informations, consultez Guide pratique pour modifier des assemblys d’interopérabilité.
Exemple
Le code suivant montre un exemple de l’interface ISATest
et de la classe SATest
dans IDL, et les types correspondants dans le code source C#.
Fichier IDL ou fichier 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 );
}
}