문제

다음과 같은 메서드 정의(IDL 표기법)를 사용하는 COM 인터페이스가 있습니다.

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

Typelib 마샬링은 COM+에 사용되고, 유형 라이브러리가 등록되며, 인터페이스의 다른 메서드는 COM+를 통해 호출할 때 제대로 작동하지만 이 메서드는 작동하지 않습니다.

서버 측은 WCHAR 배열을 awcBuffer 그리고 그 길이는 pwcBuffer, 버퍼 오버런이 발생하지 않습니다.

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

클라이언트가 COM+를 통해 이 메서드를 호출하면 버퍼 내용이 손실됩니다.특히 첫 번째 와이드 문자만 보존됩니다. 서버가 "샘플" 와이드 문자 문자열을 복사하는 경우 클라이언트는 "S" 문자열만 수신합니다.클라이언트 크기에 대한 반환 값은 S_OK이고, 클라이언트에 반환된 버퍼 길이는 서버가 복사한 것과 정확히 동일합니다.

이 문제를 해결하기 위해 마침내 BSTR로 전환했지만 유효해 보이는 전체 구조가 작동하지 않는 이유가 정말 흥미로웠습니다.

설명된 동작의 가능한 이유는 무엇입니까?

도움이 되었습니까?

해결책

IIRC, typelib Marshaller는 size_is 속성을 무시합니다. 따라서 단 1 숯만이 마샬링됩니다.

다른 팁

제이.합격이 맞습니다.Typelib 마샬러가 작동하려면 COM 인터페이스가 OLE 자동화와 호환되어야 합니다.typelib 마샬러는 oleaut32.dll에 구현되어 있으므로 이름에 힌트가 있을 것 같습니다.

[size_is]는 완벽하게 유효한 IDL이며 유효한 typelib로 컴파일되지만 typelib 마샬러는 유효한 인터페이스의 하위 집합만 처리할 수 있습니다.해당 하위 집합을 일반적으로 OLE 자동화라고 합니다.여담이지만, VB6 클라이언트는 OLE 자동화만 말할 수 있으므로 인터페이스도 사용할 수 없습니다.

IDL의 [oleautomation] 속성으로 인터페이스를 표시해 보세요.해당 주제에 대한 추가 정보를 알려줄 수 있는 경고 또는 오류 메시지가 표시되어야 합니다.

"일반" COM에서는 마샬링을 수행하기 위해 IDL에서 프록시/스텁 DLL을 생성할 수 있지만, 사용자 정의 마샬링 코드를 빌드하려고 노력하더라도 COM+가 사용자 정의 마샬링 코드를 사용할지 여부는 기억나지 않습니다.

업데이트:Juval Lowy의 저서 "COM and .NET Component Services"에서 다음 내용을 발견했습니다."...구성된 구성 요소는 사용자 정의 마샬링이 필요한 인터페이스를 사용할 수 없습니다.".그래서 나는 그 인터페이스가 COM+에서는 결코 작동하지 않을 것이라고 추측합니다.가능하다면 대신 BSTR을 사용하도록 다시 작성하세요.

몇 가지 질문 :

  • 왜 사용하지 않는다 BSTR?
  • 당신은 당신의 출처가 있습니까? GetText 기능?
  • 함수에 의해 반환 된 버퍼의 크기는 얼마입니까?
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top