CComSafeArray<VARIANT> fields;
hr = _tab_file->get_Fields(fields.GetSafeArrayPtr());

for ( LONG i = fields.GetLowerBound(), ie = fields.GetUpperBound(); i <= ie; ++i)
{
    CComVariant fld = fields.GetAt(i); // (1) raises DISP_E_BADVARTYPE (0x80020008L)

    // Next code works fine
    CComQIPtr<ITabField> field = fields.GetAt(i).punkVal; // (2) Ok
    _bstr_t fieldName;
    hr = field->get_Name(fieldName.GetAddress());
    ::OutputDebugString(fieldName + _T("\n")); // Ok
}

第(1)行:fields.GetAt(i)返回CComVariant。当我尝试将此值分配给称为复制构造函数的CComVariant fld和复制构造函数内的方法CComVariant::Copy时。它引发一个异常(“坏变量类型”,DISP_E_BADVARTYPE (0x80020008L))。
同时,线(2)运行良好。第(1)行有什么问题,以及如何解决。

编辑:这是get_Field的代码(填充SAFEARRAY)。
STDMETHODIMP TabFile::get_Fields( SAFEARRAY** fields )
{
  if(mapInfoFile_ == 0)
    return E_UNEXPECTED;
  int fieldCount = getFieldCount();
  SAFEARRAY* arr = ::SafeArrayCreateVector(VT_UNKNOWN, 0, fieldCount);
  for(LONG i = 0; i < fieldCount; i++)
  {
    QField* field = getQField(i);
    ITabField* tabField = TabField::CreateInstance();
    tabField->put_Name(_bstr_t(field->GetNameRef()));
    tabField->put_Type(field->GetNativeFieldType(i));
    ::SafeArrayPutElement(arr, &i, tabField);
    tabField->Release();
  }
  *fields = arr;
  return S_OK;
}

最佳答案



当您发现实际的数组元素类型与您要转换的类型之间不匹配时,您将需要更新getter实现和调用程序代码以相互匹配。

我个人的喜好是创建一个变体数组VT_ARRAY | VT_VARIANT并将该数组放入[out] VARIANT*参数中。调用者将其从变体展开到数组,检查数组类型,然后获取元素。这是最小的开销,并且就互操作性而言,平均而言,围绕VARIANT类型的代码是最好的(在您的特定情况下,绝对可以使用原始类型,并且完全没有变体)。

09-04 16:07