Domanda

Ho un interfaccia COM con una successiva definizione di un metodo (IDL notazione):

SCODE GetText( [in, out] ULONG* pcwcBuffer,
              [out, size_is(*pcwcBuffer)] WCHAR* awcBuffer );

Typelib marshalling viene utilizzato per COM +, la libreria dei tipi è registrata, altri metodi di lavoro dell'interfaccia allright quando chiamate tramite COM +, ma non questo metodo.

Le copie lato server Un array di WCHARs nel awcBuffer e la sua lunghezza in pwcBuffer, non si verifica mai sovraccarico del buffer.

static const wchar_t* Text = L"Sample";
STDMETHODIMP CImpl::GetText( ULONG* bufferLength, WCHAR* buffer )
{
    const int length = wcslen( Text );
    *bufferLength = length;
    memcpy( buffer, Text, length * sizeof( WCHAR ) );
    return S_OK;
}

Quando il client chiama questo metodo attraverso il contenuto del buffer COM + si perde. In particolare solo il primo carattere di larghezza è conservato - se il server copie stringa di caratteri estesi "campione", il cliente riceve solo stringa "S". Il valore di ritorno della dimensione cliente è S_OK, la lunghezza del buffer restituito al cliente è esattamente la stessa cosa che il server copiato.

Alla fine ho passato a BSTR per risolvere questo problema, ma è davvero interessante perché l'intero costrutto cercando valido non funziona.

Qual è la possibile ragione del comportamento descritto?

È stato utile?

Soluzione

IIRC, il marshaller typelib ignora l'attributo size_is - quindi, solo 1 carattere viene marshalling

.

Altri suggerimenti

J. Passaggio è giusto. Per la marshaller libreria dei tipi al lavoro, l'interfaccia COM deve essere OLE Automation compatibili. La libreria dei tipi marshaller è implementato in oleaut32.dll, quindi credo che ci sia un indizio nel nome.

[size_is] è perfettamente valido IDL, e compila in una libreria dei tipi validi, ma il gestore di marshalling typelib in grado di gestire solo un sottoinsieme di interfacce valide. Questo sottoinsieme viene solitamente indicato come OLE Automation. Per inciso, i clienti VB6 può parlare solo di automazione, in modo che non sarebbero in grado di consumare la vostra interfaccia sia.

Prova marcatura l'interfaccia con il [oleautomation] attributo nel IDL. Si dovrebbe dare un messaggio di avviso o di errore che si potrebbe puntare a maggiori informazioni sul soggetto.

In "normale" COM, si potrebbe generare un proxy / stub DLL dal IDL per fare il marshalling, ma ho paura che non ricordo se COM + userebbe il codice di marshalling personalizzato, anche se preoccupato per costruirlo .

Aggiornamento: nel libro "COM e .NET Servizi componenti" di Juval Lowy, ho trovato questa dichiarazione: " ... componenti configurati non possono utilizzare le interfacce che richiedono marshalling personalizzato ". Quindi credo che l'interfaccia non funzionerà mai in COM +. Se è possibile, ri-scrivere per usare un BSTR posto.

Un paio di domande:

  • Perché non si utilizza BSTR?
  • Avete le fonti della funzione GetText?
  • Qual è la dimensione del buffer restituita dalla funzione?
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top