2011-12-19 3 views
8

BSTR 함께 VARIANT 반환하는 함수를 사용하여 COM 개체 라이브러리에서 일하고 있습니다. 이 VARIANT 인스턴스의 값을 표시하고 TStringList 안에 저장하려면 어떻게해야합니까? 나는 명확한 대답없이 인터넷 검색을 시도했다.SAFEARRAY BSTRs 함께 VARIANT 값을 표시하는 방법

Variant V; 
String mystr; 

VarClear(V); 
TVarData(V).VType = varOleStr; 
V = ComFunction->GetValues(); //<<<<----- V is empty 
mystr = (wchar_t *)(TVarData(V).VString); 
Memo1->Lines->Add(mystr); 
VarClear(V); 

답변

4

당신은 TWideStringDynArray를 사용하고 델파이는 변환을 수행하도록 할 수 있습니다 : 당신이 BSTR에 당신의 변형의 SAFEARRAY로이를 호출 할 때

procedure LoadStringsFromVariant(const Values: TWideStringDynArray; Strings: TStrings); 
var 
    I: Integer; 
begin 
    Strings.BeginUpdate; 
    try 
    for I := Low(Values) to High(Values) do 
     Strings.Add(Values[I]); 
    finally 
    Strings.EndUpdate; 
    end; 
end; 

이 될 것입니다

는 나는 아무 성공 다음을 시도 자동으로 TWideStringDynArray으로 변환됩니다. 호환되지 않는 Variant는 런타임 오류 EVariantInvalidArgError을 발생시킵니다.

IsOK := VarIsArray(V) and (VarArrayDimCount(V) = 1) and (VarType(V) and varTypeMask = varOleStr); 
4
uses ActiveX; 

var 
    VSafeArray: PSafeArray; 
    LBound, UBound, I: LongInt; 
    W: WideString; 
begin 
    VSafeArray := ComFunction.GetValues(); 
    SafeArrayGetLBound(VSafeArray, 1, LBound); 
    SafeArrayGetUBound(VSafeArray, 1, UBound); 
    for I := LBound to UBound do 
    begin 
    SafeArrayGetElement(VSafeArray, I, W); 
    Memo1.Lines.Add(W); 
    end; 
    SafeArrayDestroy(VSafeArray); // cleanup PSafeArray 

늦게 바인딩 (CreateOleObject)를 통해 ComFunction를 작성하는 경우는 사용한다 :

var 
    v: Variant; 
v := ComFunction.GetValues; 
for i := VarArrayLowBound(v, 1) to VarArrayHighBound(v, 1) do 
begin 
    W := VarArrayGet(v, [i]); 
    Memo1.Lines.Add (W); 
end; 
변종이 작업을 수행 할 수 있습니다 BSTR의 안전 배열을 보유하고있는 경우

확인하려면
2

이 VARIANT 인스턴스의 값을 어떻게 표시하고 TStringLi에 저장할 수 있습니까? 성?

는 COM VARIANT 구조체는 SAFEARRAY에 대한 포인터 parraypparray 데이터 구성원, 예를 가지고

VARIANT V; 
LPSAFEARRAY sa = V_ISBYREF(&V) ? V_ARRAYREF(&V) : V_ARRAY(&V); 
은 VCL Variant 클래스, 한편, LPSAFEARRAY 변환 연산자를 가지고

정의되었으므로 직접 할당 할 수 있습니다 (예 : varByRef 플래그가없는 Variant.VType 필드 인 경우에만 해당). 예 :

당신이 SAFEARRAY 포인터를 일단
Variant V; 
LPSAFEARRAY sa = V; 

어느 쪽이든의 BSTR 값에 액세스 할 수 SafeArray는 API를 사용하여, 예를 들면 :

bool __fastcall VariantToStrings(const Variant &V, TStrings *List) 
{ 
    // make sure the Variant is holding an array 
    if (!V_ISARRAY(&V)) return false; 

    // get the array pointer 
    LPSAFEARRAY sa = V_ISBYREF(&V) ? V_ARRAYREF(&V) : V_ARRAY(&V); 

    // make sure the array is holding BSTR values 
    VARTYPE vt; 
    if (FAILED(SafeArrayGetVartype(sa, &vt))) return false; 
    if (vt != VT_BSTR) return false; 

    // make sure the array has only 1 dimension 
    if (SafeArrayGetDim(sa) != 1) return false; 

    // get the bounds of the array's sole dimension 
    LONG lBound = -1, uBound = -1; 
    if (FAILED(SafeArrayGetLBound(sa, 0, &lBound))) return false; 
    if (FAILED(SafeArrayGetUBound(sa, 0, &uBound))) return false; 

    if ((lBound > -1) && (uBound > -1)) 
    { 
     // access the raw data of the array 
     BSTR *values = NULL; 
     if (FAILED(SafeArrayAccessData(sa, (void**)&values))) return false; 
     try 
     { 
      List->BeginUpdate(); 
      try 
      { 
       // loop through the array adding the elements to the list 
       for (LONG idx = lBound; l <= uBound; ++idx) 
       { 
        String s; 
        if (values[idx] != NULL) 
         s = String(values[idx], SysStringLen(values[idx])); 
        List->Add(s); 
       } 
      } 
      __finally 
      { 
       List->EndUpdate(); 
      } 
     } 
     __finally 
     { 
      // unaccess the raw data of the array 
      SafeArrayUnaccessData(sa); 
     } 
    } 

    return true; 
} 

VarClear (V); TVarData (V) .VType = varOleStr;

전혀 필요하지 않습니다. VCL Variant 클래스는 자신을 빈 상태로 초기화하므로 을 할당 할 필요가 없습니다. 이후에 즉시 Variant 전체에 새 값을 할당 할 것이기 때문입니다.

V = ComFunction-> GetValues ​​(); V는 다음 GetValues()로 시작하는 빈 Variant을 반환, 비어있는 경우 // < < < < ----- V는

비어 있습니다.

mystr = (wchar_t *) (TVarData (V) .VString);

TVarData::VStringAnsiString& 참조 아닌 wchar_t* 포인터이다. String에 VCL Variant (안 COM VARIANT를) 변환하려면, 단지 RTL 당신을위한 내용을 작품 그대로를 할당하고 보자

String mystr = V; 
관련 문제