Question

J'ai une interface COM avec une définition de méthode suivante (notation IDL):

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

Typelib marshaling est utilisé pour COM +, la bibliothèque de types est enregistrée, d'autres méthodes de travail d'interface Allright lorsque appelé par COM +, mais pas cette méthode.

Les copies de côté de serveur de réseau d'un de WCHARs dans le awcBuffer et sa longueur en pwcBuffer, aucun débordement de tampon se produit jamais.

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;
}

Lorsque le client appelle cette méthode par COM + le contenu du tampon est perdu. Plus précisément que la première grande omble chevalier est conservé - si les copies du serveur « Sample » grande chaîne de caractères, le client ne reçoit que la chaîne « S ». La valeur de retour de la taille du client est S_OK, la longueur du tampon renvoyé au client est exactement le même que ce que le serveur copié.

J'ai finalement passé à Bstr pour résoudre ce problème, mais il est vraiment intéressant, pourquoi toute construction valide la recherche ne fonctionne pas.

Quelle est la raison possible du comportement décrit?

Était-ce utile?

La solution

IIRC, le placier typelib ignore l'attribut size_is - ainsi que 1 caractère est marshalé

.

Autres conseils

J. Passing est juste. Pour le placier typelib fonctionne, l'interface COM doit être compatible OLE Automation. Le placier typelib est mis en œuvre oleaut32.dll, donc je pense qu'il ya un indice dans le nom.

[size_is] est parfaitement valide IDL et compile en un typelib valide, mais le marshaleur typelib ne peut gérer un sous-ensemble d'interfaces valides. Ce sous-ensemble est généralement appelé OLE Automation. En aparté, les clients VB6 ne peut parler OLE Automation, de sorte qu'ils ne seraient pas en mesure de consommer votre interface soit.

Essayez de sélectionner l'interface avec l'attribut [oleautomation] dans votre IDL. Il devrait vous donner un message d'avertissement ou d'une erreur qui pourrait vous indiquer plus d'informations sur le sujet.

Dans « normal » COM, vous pouvez générer une DLL proxy / stub de votre IDL pour faire le rassemblement, mais je crains que je ne me souviens pas si COM + utiliserait votre code de triage personnalisé même si vous pris la peine de le construire .

Mise à jour: dans le livre "COM et .NET Component services" de Juval Lowy, je trouve cette déclaration: " ... composants configurés ne peuvent pas utiliser les interfaces qui nécessitent marshaling personnalisées ". Donc je suppose que cette interface ne fonctionnera jamais dans COM +. Si vous le pouvez, ré-écrire à utiliser un BSTR à la place.

Couple de questions:

  • Pourquoi ne vous utilisez BSTR?
  • Avez-vous des sources de la fonction GetText?
  • Quelle est la taille de la mémoire tampon retournée par la fonction?
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top