Pergunta

Eu tenho uma interface COM com uma definição de método seguinte (notação IDL):

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

Typelib empacotamento é usado para COM +, a biblioteca tipo é registrado, outros métodos do allright trabalho interface quando chamado através de COM +, mas não este método.

As cópias do lado do servidor uma matriz de WCHARs na awcBuffer e o seu comprimento em pwcBuffer, sem saturação de buffer nunca ocorre.

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 o cliente chama esse método através do COM + o conteúdo do buffer se perde. Especificamente apenas o primeiro caractere de largura é preservada - se o servidor copia cadeia de caracteres "exemplo" de largura, o cliente recebe apenas "S" string. O valor de retorno sobre o tamanho do cliente é S_OK, o tamanho do buffer retornado para o cliente é exatamente o mesmo que o servidor copiado.

Eu finalmente mudou para BSTR para resolver este problema, mas é realmente interessante porque toda a construção olhando válida não funciona.

Qual é a possível razão do comportamento descrito?

Foi útil?

Solução

IIRC, o marshaller typelib ignora o atributo size_is -. Assim, apenas 1 char é empacotado

Outras dicas

J. Passagem é certo. Para o marshaller typelib para o trabalho, a interface COM deve ser de automação OLE compatíveis. O marshaller typelib é implementado em oleaut32.dll, então eu acho que há uma pista no nome.

[size_is] é perfeitamente válido IDL e compilado em um typelib válido, mas o empacotador typelib só pode lidar com um subconjunto de interfaces válidos. Esse subconjunto é normalmente referido como OLE Automation. Como um aparte, os clientes VB6 só posso falar OLE Automation, para que eles não seriam capazes de consumir a sua interface de qualquer um.

Tente marcar sua interface com o atributo [oleautomation] em sua IDL. Deve dar-lhe uma mensagem de aviso ou de erro que pode apontar-lhe mais informações sobre o assunto.

Em "normal" COM, você poderia gerar a / stub DLL do proxy do seu IDL para fazer a triagem, mas eu tenho medo que eu não me lembro se COM + usaria seu código marshalling personalizado mesmo se deu ao trabalho de construí-lo .

Update: no livro de Juval Lowy "COM e .NET Services Component", achei que esta declaração: " ... componentes configurados não podem usar interfaces que exigem empacotamento personalizado ". Então eu acho que a interface nunca vai funcionar no COM +. Se você puder, re-escrita para usar um BSTR vez.

par de perguntas:

  • Por que você não está usando BSTR?
  • Você tem as fontes da função GetText?
  • Qual é o tamanho do buffer retornado pela função?
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top