2016-06-30 32 views
0

일부 데이터를 교환 할 수 있도록 DCOM 서버와 클라이언트를 작성하고 싶습니다. 양측은 MS Visual Studio 2008을 사용하여 컴파일되고, 클라이언트는 순수 WinAPI를 사용하여 연결됩니다. 프록시/스텁은 별도의 dll입니다 (이 경우 중요). 문제는, 문자열 배열을 반환 할 수 없다는 것입니다 (클라이언트가 빈 문자열 배열을 받으면 제대로 채워집니다).DCOM에서 [out] 매개 변수로 SAFEARRAY (BSTR) 문자열을 반환하지 못했습니다.

서버

: 스튜디오에 의해 생성 된

[id(7)] HRESULT foo([in] int arg1, [out] SAFEARRAY(int)* arg2, [out] SAFEARRAY(BSTR)* arg3); 

구현, 헤더 : COM 인터페이스의 IDL 선언이 방법을 가지고

HRESULT STDMETHODCALLTYPE CoClass::foo(int arg1, SAFEARRAY** arg2, SAFEARRAY** arg3){ 
    SAFEARRAYBOUND bounds; 
    bounds.cElements = arg1; 
    bounds.lBound = 0; 
    *arg2 = SafeArrayCreate(VT_INT, 1, &bounds); 
    *arg3 = SafeArrayCreate(VT_BSTR, 1, &bounds); 
    for(LONG i=0; i<arg1; ++i){ 
     int int_value = 42; 
     BSTR string_value = SysAllocString(L"Hello"); 
     //string_value is correct here 
     SafeArrayPutElement(*arg2, &i, &int_value); 
     SafeArrayPutElement(*arg3, &i, &string_value); 
     //string_value isn't destroyed here (explicitly, at least) 
    } 
    return ERROR_SUCCESS; 
} 

클라이언트 : 스튜디오에서 생성 된 헤더를 포함 :

virtual /* [id] */ HRESULT STDMETHODCALLTYPE foo(
    /* [in] */ int arg1, 
    /* [out] */ SAFEARRAY * *arg2, 
    /* [out] */ SAFEARRAY * *arg3) = 0; 

발신자 코드 (pInterface가 제대로 초기화되고, 다른 호출이 성공) :

SAFEARRAY *pInts = NULL, *pStrings = NULL; 
HRESULT error = pInterface->foo(23, &pInts, &pStrings); 
// in debugger: 
// error is ERROR_SUCCESS, pInts filled properly, 
// pStrings is an array of 23 NULLs 

기타 자세한 사항 :

  • IDL 파일 ID (7)와 다른 방법이 없다;
  • [out] BSTR *str을 사용하면 문자열이 제대로 반환됩니다.
  • pInterfaceCoCreateInstanceEx에서 호출됩니다.
  • 시스템에 이전 버전의 서버가 없습니다.
  • 코드는 Windows XP에서 일부 업데이트없이 실행되므로 Visual Studio 2008을 사용하는 것은 우회하기 어려운 제약 사항입니다.

내가 뭘 잘못하고 있는지 알 수있는 사람이 있습니까?

+1

BSTR 이미 포인터 패스이다 SAFEARRAY에 요소를 추가하는 구문 intBSTR 다르다 & string_value 대신 string_value. –

+0

@HansPassant ...이 작업을 수행했습니다. 고맙습니다. 답을 쓰고 싶습니까, 아니면 직접해야합니까? – Abstraction

+0

나는 정확한 답을 쓰는 법을 지금 알고 있다고 확신한다. –

답변

2

댓글 섹션에서 대답은 Hans Passant입니다.

해답 :

// SAFEARRAY **intArray, **stringArray; LONG i; 
int int_value = 42; 
BSTR string_value = SysAllocString(L"Hello"); 

SafeArrayPutElement(*intArray, &i, &int_value); 
//SafeArrayPutElement(*stringArray, &i, &string_value); //WRONG! 
SafeArrayPutElement(*stringArray, &i, string_value); //Right 

참고 읽기 구문 동일 함 :

// SAFEARRAY *intArray, *stringArray; LONG i; 
int int_value; 
BSTR string_value; 

SafeArrayGetElement(intArray, &i, &int_value); 
SafeArrayGetElement(stringArray, &i, &string_value);