[C# 2.0] COM, Generics

J’ai un souci bien génant avec un projet d’une librairie de classes .net 2.0b à exposer en COM.
Mon soucis vient du fait qu’une de mes classes est dérivée d’une classe abstraite générique. Tout est pourtant fait comme il faut, mais le compilo me râle dessus et refuse d’exposer ma classe dans mon objet COM.

Mes classes sans détailler leur contenu (inutile) (faire attention aux espaces de noms) :

[code]using System;
using System.Runtime.InteropServices;

namespace PMLInterop
{
   [Guid(« 36DC388E-80FD-467b-8648-E9A72F4E8F8D »)]
   [ClassInterface(ClassInterfaceType.None)]
   [ProgId(« PMLInterop.ReqInfoProduit »)]
   public class ReqInfoProduit : MessageBase<PMLInteropIL.ReqInfoProduit>, IReqInfoProduit
   {

   }
}[/code]

[code]using System;
using System.Runtime.InteropServices;

namespace PMLInterop
{
   [Guid(« 2E4452EC-86AA-46d1-A303-DFF7C4B444D9 »)]
   [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
   public interface IReqInfoProduit
   {

   }
}[/code]

[code]using System;
using System.Runtime.InteropServices;

namespace PMLInterop
{
   [Guid(« 030654A0-7B86-4344-A988-180793B21A5F »)]
   [ClassInterface(ClassInterfaceType.None)]
   public abstract class MessageBase : IMessage
   {

   }
}[/code]

[code]using System;
using System.Runtime.InteropServices;

namespace PMLInterop
{
   [Guid(« CABAFB9C-38FC-4fbf-9731-F8C59FCF0C13 »)]
   [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
   public interface IMessage
   {

   }
}[/code]

La classe suivante est utilisée par PMLInterop.ReqInfoProduit qui dérive de la classe abstraite générique PMLInterop.MessageBase. Bien faire attention aux espaces de noms, PMLInteropIL n’est pas censée être une librairie exposée COM.

[code]using System;

namespace PMLInteropIL
{
   public class ReqInfoProduit
   {

   }
}[/code]

Je n’ai pas détaillé toutes mes classes.
Pour info, j’implémente mes interfaces de façon implicite dans mon code.

Mon problème est plus un problème de compréhension de l’erreur: je comprend pas le message d’erreur du type library exporter. Je ne vois pas où mettre [ComDefaultInterface(typeof(…))] pour régler le soucis.

Je veux seulement pouvoir exporter en COM ma classe PMLInterop.ReqInfoProduit comprenant les propriétés et méthodes de l’interface PMLInterop.IReqInfoProduit et les propriétés et méthodes de PMLInterop.IMessage, utilisé par la classe générique abstraite MessageBase.

Les beta c’est bien, mais côté support… c’est pas terrible.
A part sur ce blog, j’ai trouvé personne rencontrant ce problème.

Si vous pouvez m’aider, je fournirai bières et putes à volonté :stuck_out_tongue:

A priori essais de mettre [ComDefaultInterface(typeof(IReqInfoProduit))} devant ta classe ReqInfoProduit .
Mais il reste peut-être encore quelques bugs non réglés au niveau COM Interop / génériques

[s]J’ai du mettre [ClassInterface(ClassInterfaceType.None)] sur la classe passée en variable type de ma classe abstraite générique, et le compilo me râle plus dessus.

Pour rappel:
public class ReqInfoProduit : MessageBase<PMLInteropIL.ReqInfoProduit>, IReqInfoProduit

C’est la classe que j’ai mis en gras ci-dessus que j’ai du tagger avec [ClassInterface(ClassInterfaceType.None)].[/s]
J’ai pas les outils pour vérifier le .tlb (notamment OLEVIEW), donc je confirmerai demain depuis le boulot si cela a bien réglé le problème.

Merci tout de même girafologue :stuck_out_tongue:

edit: bon… j’ai acheté des yeux entre deux, en fait rien n’a été réglé du tout…le problème reste entier

Bien… second problème maintenant.

J’ai viré toutes mes histoires de generics, tant pis, on attendra plus de doc la dessus…
Maintenant le problème vient de mon objet COM lui même.

Voici l’IDL simplifié de coclass ReqInfoProduit:

[ &nbsp;uuid(36DC388E-80FD-467B-8648-E9A72F4E8F8D), &nbsp;version(1.0), &nbsp;custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, PMLInterop.ReqInfoProduit) ] coclass ReqInfoProduit { &nbsp; &nbsp;interface _Object; &nbsp; &nbsp;dispinterface IMessage; &nbsp; &nbsp;[default] dispinterface IReqInfoProduit; };

J’ai essayé d’utiliser mon objet COM depuis une simple page ASP (le vieux, pas ASP.NET) et j’ai pu utiliser les propriétés et méthodes issues de IReqInfoProduit, mais pas de IMessage : “Cet objet ne gère pas cette propriété ou cette méthode”.

Apparamment ASP n’utilise que l’interface par défaut de l’objet COM.
Est-ce coutournable ou bien est-ce une limitation de ASP/VBScript ?

En VBS et JS tu ne peux utiliser que les méthodes de l’interface par défaut (celle qui dérive effectivement de IDispatch). Cela n’est pas du spécifiquement à .Net / ASP, mais aux languages qui utilisent la liaison tardive aux objets COM. Pour règler ton problème, fais dériver ton interface IReqInfoProduit de IMessage si possible ou crées une nouvelle interface dérivant de IMessage et IReqInfoProduit que tu utiliseras comme interface par défaut.

J’ai essayé les deux méthodes, et dans les deux cas cela ne fonctionne pas.
Je remet toutes mes classes et interfaces à jour :

[codebox]// Generated .IDL file (by the OLE/COM Object Viewer)

//
// typelib filename: PMLInterop.tlb

[
uuid(5A3F6CD4-471E-325F-8F7B-47E49889B41F),
version(1.0),
custom(90883F05-3D28-11D2-8F17-00A0C9A6186D, PMLInterop, Version=1.0.1868.19083, Culture=neutral, PublicKeyToken=07ef0da0a555fbd2)

]
library PMLInterop
{
// TLib : // TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
importlib(« mscorlib.tlb »);
// TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib(« Stdole2.tlb »);

// Forward declare all types defined in this typelib
dispinterface IMessage;
dispinterface IReqInfoProduit;
dispinterface IReqInfoProduitDisp;

[
  uuid(CABAFB9C-38FC-4FBF-9731-F8C59FCF0C13),
  version(1.0),
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, PMLInterop.IMessage)    

]
dispinterface IMessage {
    properties:
    methods:
        [id(0x60020000), propget]
        BSTR Officine();
        [id(0x60020000), propput]
        void Officine([in] BSTR rhs);
        [id(0x60020002), propget]
        BSTR Action();
        [id(0x60020002), propput]
        void Action([in] BSTR rhs);
        [id(0x60020004), propget]
        BSTR EnReponseA();
        [id(0x60020004), propput]
        void EnReponseA([in] BSTR rhs);
        [id(0x60020006), propget]
        BSTR LastError();
        [id(0x60020007)]
        VARIANT_BOOL Send();
        [id(0x60020008)]
        void Close();
};

[
  uuid(2E4452EC-86AA-46D1-A303-DFF7C4B444D9),
  version(1.0),
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, PMLInterop.IReqInfoProduit)    

]
dispinterface IReqInfoProduit {
    properties:
    methods:
        [id(0x60020000), propget]
        BSTR Reference();
        [id(0x60020000), propput]
        void Reference([in] BSTR rhs);
        [id(0x60020002)]
        void AddLine(
                        [in] BSTR codeproduit, 
                        [in] short quantite);
        [id(0x60020003),
          custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AddLine)]
        void AddLine_2(
                        [in] BSTR typecode, 
                        [in] BSTR codeproduit, 
                        [in] short quantite);
        [id(0x60020004),
          custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, AddLine)]
        void AddLine_3(
                        [in] BSTR typecode, 
                        [in] BSTR codeproduit, 
                        [in] short quantite, 
                        [in] BSTR designation);
};

[
  uuid(EAD0D869-2F1A-43C2-B281-EC29255C3F37),
  version(1.0),
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, PMLInterop.IReqInfoProduitDisp)    

]
dispinterface IReqInfoProduitDisp {
    properties:
    methods:
};

[
  uuid(36DC388E-80FD-467B-8648-E9A72F4E8F8D),
  version(1.0),
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, PMLInterop.ReqInfoProduit)
]
coclass ReqInfoProduit {
    interface _Object;
    dispinterface IMessage;
    [default] dispinterface IReqInfoProduitDisp;
    dispinterface IReqInfoProduit;
};

};[/codebox]

IReqInfoProduitDisp est bien en interface par défaut, mais ne contient aucune méthode ni propriété, ASP ne voit donc… plus rien… :stuck_out_tongue: