Delphi将数组变量转换为字符串

5

在我的Delphi程序中,我正在与一个Web服务进行通信。

在导入WSDL时,我创建了以下函数-

    function  call(const sessionId: WideString; const resourcePath: WideString;
 const args: Variant): Variant; stdcall;

现在当我在代码中调用这个函数时,我想看到返回的值是什么。
var
p:WideString;
v:variant;
VarArray:variant;
begin

   //varArray := VarArrayCreate([0,50],varVariant);

   v := (httprio1 as  Mtest).call(a,'giftgit.gift', '28184');


   //p := VarArrayget(V,[1] ) ;
   p := vartostr(v[1]);

我在最后一行遇到了这个错误

无法将类型为(数组变量)的变量转换为类型为(字符串)的变量

我尝试使用varArray,但仍然出现相同的问题。 我该怎么解决?

谢谢

备注:该段内容涉及IT技术,可能需要具备一定的专业知识才能理解。


2
你知道Web服务调用应该返回什么吗? - Ondrej Kelle
嗨,这个 Web 服务是由第三方用 PHP 制作的,他们说它应该返回一个数组,然后将其转换为 XML。 - James
2
很遗憾,这仍然是模糊的。具体是什么类型的数组?您能发布生成响应的PHP代码吗? - Ondrej Kelle
1
VarType(v) 返回的是什么?使用 AND 运算符将其与 varTypeMask 常量进行掩码处理,以查找数组中各个元素的数据类型,即:ElementType := VarType(v) and varTypeMask;,然后使用 VarArray...() 函数(VarArrayLowBound()VarArrayHighBound()VarArrayGet() 等)来访问这些元素。 - Remy Lebeau
1个回答

7
错误表明V[1]是变体数组。您可以使用VarIsArray(V[1])检查它是否确实是变体数组。
我有几种方法可以帮助您显示它:
  TPsVarDataType = (
    vdtDefault, // varEmpty
    vdtNull,
    vdtSmallint,
    vdtInteger,
    vdtSingle,
    vdtDouble,
    vdtCurrency,
    vdtDate,
    vdtOleStr,  // varOleStr, varString, varUString
    vdtDispatch,
    vdtError,
    vdtBoolean,
    vdtVariant,
    vdtUnknown,
    vdtDecimal,
    vdtUndefined,
    vdtShortint,
    vdtByte,
    vdtWord,
    vdtLongWord,
    vdtInt64,
  {$IFDEF D2009_OR_LATER}
    vdtUInt64,
  {$ENDIF}
    vdtUnsupported
    {Usupported types
    VT_UI8  = 21,
    VT_INT  = 22,
    VT_UINT = 23,
    VT_VOID = 24,
    VT_HRESULT  = 25,
    VT_PTR  = 26,
    VT_SAFEARRAY    = 27,
    VT_CARRAY   = 28,
    VT_USERDEFINED  = 29,
    VT_LPSTR    = 30,
    VT_LPWSTR   = 31,
    VT_RECORD   = 36,
    VT_FILETIME = 64,
    VT_BLOB = 65,
    VT_STREAM   = 66,
    VT_STORAGE  = 67,
    VT_STREAMED_OBJECT  = 68,
    VT_STORED_OBJECT    = 69,
    VT_BLOB_OBJECT  = 70,
    VT_CF   = 71,
    VT_CLSID    = 72,
    VT_VERSIONED_STREAM = 73,
    VT_BSTR_BLOB    = 0xfff,
    VT_VECTOR   = 0x1000,
    VT_ARRAY    = 0x2000,
    VT_BYREF    = 0x4000,
    VT_RESERVED = 0x8000,
    VT_ILLEGAL  = 0xffff,
    VT_ILLEGALMASKED    = 0xfff,
    VT_TYPEMASK = 0xfff
    }
  );

const
  SPsVarDataTypes: array [TPsVarDataType] of string  = (
    'Default',
    'Null',
    'Smallint',
    'Integer',
    'Single',
    'Double',
    'Currency',
    'Date',
    'OleStr',
    'Dispatch',
    'Error',
    'Boolean',
    'Variant',
    'Unknown',
    'Decimal',
    'Undefined',
    'Shortint',
    'Byte',
    'Word',
    'LongWord',
    'Int64',
  {$IFDEF D2009_OR_LATER}
    'UInt64',
  {$ENDIF}
    'Unsupported'
  );

const
  SPsVarDataTypes: array [TPsVarDataType] of string  = (
    'Default',
    'Null',
    'Smallint',
    'Integer',
    'Single',
    'Double',
    'Currency',
    'Date',
    'OleStr',
    'Dispatch',
    'Error',
    'Boolean',
    'Variant',
    'Unknown',
    'Decimal',
    'Undefined',
    'Shortint',
    'Byte',
    'Word',
    'LongWord',
    'Int64',
  {$IFDEF D2009_OR_LATER}
    'UInt64',
  {$ENDIF}
    'Unsupported'
  );

  SPsVarArray = 'Array of %s';
  SPsVarByRef = '%s (Reference)';

function VariantToStr(V: Variant; IncludeType: Boolean = False): string;
begin
  if VarIsArray(V) then
    Result := VarArrayToStr(V)
  else
    case VarType(V) of
      varError:
        Result := Format('Error($%x)', [TVarData(v).VError]);
      varNull:
        Result := '#NULL';
      varEmpty:
        Result := '#EMPTY';
      varDate:
        Result := FormatDateTime(ShortDateFormat + ' ' + LongTimeFormat + '.zzz', V)
    else
      Result := VarToStr(V);
    end;
  if IncludeType then
    Result := Format('%s{%s}', [Result, VarTypeToString(VarType(V))]);
end;


function VarArrayToStr(v: Variant; Delimiter: Char = #0; LineDelimiter: Char =
    #13): string;
var
  i,j,d: Integer;
  line: string;
begin
  if VarIsArray(v) then
  begin
    if Delimiter = #0 then
      Delimiter := ListSeparator;
    if LineDelimiter = #0 then
      LineDelimiter := ListSeparator;
    d := VarArrayDimCount(v);
    // The elements
    case d of
      1:
      begin
        Result := '';
        for i := VarArrayLowBound(v,1) to VarArrayHighBound(v,1) do
          Result := Result + VariantToStr(v[i]) + Delimiter;
        if Length(Result) > 0 then
          SetLength(Result, Length(Result)-1);
      end;
      2:
      begin
        Result := '';
        if (VarArrayLowBound(v,1) <= VarArrayHighBound(v,1)) and
          (VarArrayLowBound(v,2) <= VarArrayHighBound(v,2)) then
        begin
          for i := VarArrayLowBound(v,1) to VarArrayHighBound(v,1) do
          begin
            line := '';
            for j := VarArrayLowBound(v,2) to VarArrayHighBound(v,2) do
              line := line + VariantToStr(v[i,j]) + Delimiter;
            if Length(Result) > 0 then
              SetLength(line, Length(line)-1);
            Result := Result + LineDelimiter + Format('[%s]', [line]);
          end;
        end;
      end // 2
    else
      Result := 'Array Dim=' + IntToStr(d);
    end;
    Result := Format('[%s]', [Result]);
  end
  else
    Result := VarToStr(v);
end;


function VarTypeToString(varType: Integer): string;
var
  T: TPsVarDataType;
begin
  if varType = varString then
    Result := 'string'
  else
  begin
    T := VarTypeToPsVarDataType(varType);
    if T = vdtUnSupported then
      Result := IntToStr(varType and varTypeMask)
    else
      Result := SPsVarDataTypes[T];
  end;
  if (varType and varArray) <> 0 then
    Result := Format(SPsVarArray,[Result]);

  if (varType and varByRef) <> 0  then
    Result := Format(SPsVarByRef,[Result]);
end;


function VarTypeToPsVarDataType(Value: Word): TPsVarDataType;
var
  v: Word;
begin
  debugEnter('VarTypeToPsVarDataType');
  v := Value and varTypeMask;
  debugInt('Value', v);
  if v < Word(vdtUnsupported) then
    result := TPsVarDataType(v)
  else if v = varString then
    result := vdtOleStr
  {$IFDEF D2009_OR_LATER}
  else if v = varUString then
    result := vdtOleStr
  {$ENDIF}
  else
    result := vdtUnsupported;
  debugLeave;
end;

function PsVarDataTypeToVarType(Value: TPsVarDataType; IsArray: Boolean =
    False): Word;
begin
  if Value = vdtUnsupported then
    Result := varEmpty
  else
  begin
    Result := Word(Value);
    if IsArray then
      Result := Result or varArray;
  end;
end;

更新于2012年9月20日:看起来我错过了字符串常量,已添加。 更新于2012年11月2日:TPsVarDataType、VarTypeToPsVarDataType()和VarTypeToPsVarDataType()。


TPsVarDataType是什么?它似乎不是一个标准类。 - Max
是的,那个确实漏了。我添加了它和一些转换函数。不过似乎我没有正确地掌握风格... - Jouni Aro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接