Domanda

Ho trovato che quando aggiungo nuovi eventi a un'interfaccia COM / IDL esistente, a volte incorrere in problemi strani meno che non siano aggiunti alla fine dell'interfaccia.

Ad esempio, dire che ho la seguente interfaccia:

interface IMyEvents
{
    HRESULT FooCallback(
        [in] long MyParam1,
        [in] long MyParam2,
        [in] long MyParam3);

    HRESULT BarCallback(
        [in] long MyParam1,
        [in] BSTR MyParam2,
        [in] BSTR MyParam3);
};

Ora diciamo che voglio aggiungere un nuovo evento di callback, NewCallback. Se posso aggiungere che in questo modo, io tendono a non avere alcun problema quando l'evento viene generato attraverso COM:

interface IMyEvents
{
    HRESULT FooCallback(
        [in] long MyParam1,
        [in] long MyParam2,
        [in] long MyParam3);

    HRESULT BarCallback(
        [in] long MyParam1,
        [in] BSTR MyParam2,
        [in] BSTR MyParam3);

    /* New event added to the end */
    HRESULT NewCallback(
        [in] BSTR MyParam1,
        [in] BSTR MyParam2,
        [in] BSTR MyParam3);
};

Ma se aggiungo in questo modo, posso incorrere in problemi di ogni genere (ad esempio buffer overrun) quando l'evento viene generato.

interface IMyEvents
{
    HRESULT FooCallback(
        [in] long MyParam1,
        [in] long MyParam2,
        [in] long MyParam3);

    /* New event added to the middle */
    HRESULT NewCallback(
        [in] BSTR MyParam1,
        [in] BSTR MyParam2,
        [in] BSTR MyParam3);

    HRESULT BarCallback(
        [in] long MyParam1,
        [in] BSTR MyParam2,
        [in] BSTR MyParam3);
};

Sto indovinando che ha qualcosa a che fare con punti di ingresso DLL, offset di indirizzo, o qualcosa di simile. O forse è perché non ho ri-costruito qualcosa correttamente, e l'aggiunta a fine permette di lavorare per pura fortuna.

Qualcuno può spiegare questo comportamento?

È stato utile?

Soluzione

Non sono tenuti a modificare un interfaccia COM esistente. I clienti che non sono stati compilati con la modifica non sono a conoscenza di esso e continueranno chiamando come avevano fatto prima del cambiamento.

Il risultato è che i clienti esistenti chiamano BarCallback con un intero lungo, ma invece ottenere NewCallback che pensa che questo intero lungo è un BSTR. I risultati sono spesso sgradevoli.

Si otterrà problemi simili con l'aggiunta di nuove funzioni alla fine. Più vecchio oggetto COM non hanno la nuova funzione implementata ed è probabile che proprio in crash quando si tenta di chiamare.

Tuttavia, se non si dispone di client esistenti in natura con la vecchia interfaccia, basta assicurarsi di annullare la registrazione di tutto e sostituire l'oggetto, i clienti ei proxy e stub generati.

Altri suggerimenti

Non credo che abbia niente a che fare con l'aggiunta del codice alla fine.

Mi ricordo di aggiungere la funzione verso la metà del file di interfaccia.

Ma ogni volta che lo si modifica, in modo che si annullare la registrazione del dll e rigenerare nuovo tutti i file. (Come indicato nel precedente post) Sii preciso in tutte le fasi, perché il debug di questa roba in fase di esecuzione è dura.

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