Domanda

Questa è solo una domanda su come scrivere il mio codice per un'importazione COM.

La mia comprensione della corretta implementazione delle interfacce di interoperabilità è che il criterio principale è che:

  1. Tutte le firme dei metodi devono corrispondere in modo compatibile
  2. I metodi devono apparire esattamente nello stesso ordine nell'interfaccia .Net come nell'interfaccia non gestita
  3. Quando l'interfaccia non gestita eredita da un'altra interfaccia non gestita, l'implementazione gestita deve prima dichiarare i membri dell'interfaccia di livello base, iniziando con l'interfaccia più base.

La mia domanda è; cosa devo fare, rispetto all'ordine in cui appaiono i membri, se l'interfaccia che sto importando è ereditata da un'altra interfaccia e sovrascrive / nasconde uno o più membri nell'interfaccia di base? Dove va la dichiarazione dei membri dell'interfaccia? Innanzitutto, dove l'ha dichiarata l'interfaccia di base? O rimosso dalla sua posizione originale e collocato dove lo dichiara l'interfaccia derivata?

[uuid(31d1c294-1dd2-11b2-be3a-c79230dca297)]
interface BaseComInterface
{
    void method1();
    void method2();
    void method3();
}

[uuid(fab51c92-95c3-4468-b317-7de4d7588254)]
interface DerivedComInterface : BaseComInterface
{
    void method1();
    void method4();
    void method5();
}

Ora per il codice C #:

[Guid("fab51c92-95c3-4468-b317-7de4d7588254"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDerivedComInterface
{
    void method1(); // do I remove this one?
    void method2();
    void method3();
    void method1(); // or this one?
    void method4();
    void method5();
}
È stato utile?

Soluzione

Hai un esempio di qualcuno che lo sta effettivamente facendo? Mentre è perfettamente legale in COM avere lo stesso nome per un metodo in un'interfaccia e in un'altra interfaccia da essa derivata, rende difficile o impossibile lavorare con l'interfaccia derivata in quasi tutti gli ambienti di sviluppo. Ciò include l'implementazione e la chiamata di eventuali oggetti COM basati sull'interfaccia.

Non è possibile eseguire l'override o l'occultamento in un'interfaccia COM. Un'interfaccia COM è solo un contratto per il modo in cui l'interfaccia binaria di un oggetto verrà disposta in memoria, i nomi dei metodi nella definizione dell'interfaccia sono privi di significato tranne che per gli strumenti. Nel tuo caso, BaseComInterface promette una 'vtable' con sei metodi, i primi tre corrispondono alle firme dei metodi IUnnown e i tre successivi corrispondono alle firme dei tre metodi che hai dato, tutti nell'ordine corretto. D'altra parte DerivedComInterface promette una 'vtable' che include nove metodi, ancora una volta le prime tre firme corrispondono ai metodi IUnnown, le tre successive corrispondono alle firme dei metodi BaseComInterface e le ultime tre corrispondono ai tre metodi univoci a DerivedComInterface. I nomi di questi metodi sono irrilevanti ad eccezione dell'IDE, degli strumenti e del compilatore che richiedono i nomi per trovare i puntatori "vtable".

Quindi, fondamentalmente, in C # oltre a C, C ++ e alcuni altri linguaggi, per implementare DerivedComInterface uno dei nomi dei metodi dovrebbe essere decorato per distinguere lo slot 'vtable' dall'altro.

Per rispondere alla tua domanda, non rimuoveresti nessuno dei due metodi poiché entrambi devono essere presenti per adempiere al contratto COM:

[Guid("fab51c92-95c3-4468-b317-7de4d7588254"), ComImport,  InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDerivedComInterface
{
    void method1(); 
    void method2();
    void method3();
    void method1_2(); //Decorated to distinguish from base interface method.
    void method4();
    void method5();
}

Questo ignora cosa accadrebbe se queste interfacce derivassero da IDispatch piuttosto che da IUnknown, un disordine nel quale non vorrei entrare. Inoltre, ricorda che se il tuo idl definisce davvero i metodi come ritorno vuoto, devi decorare i tuoi metodi C # con l'attributo PreserveSig.

Altri suggerimenti

Ti suggerisco di utilizzare implementazioni esplicite dei membri dell'interfaccia per evitare conflitti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top