title: usage differences between _variant_t, COleVariant, CComVariant, and VARIANT and using SAFEARRAY variations
body: <p>I am investigating several Visual Studio 2015 C++ project types which use ADO to access an SQL Server database. The simple example performs a select against a table, reads in the rows, updates each row, and updates the table.</p>
  
  <p>The MFC version works fine. The Windows console version is where I am having a problem updating the rows in the recordset. The <code>update()</code> method of the recordset is throwing a COM exception with the error text of:</p>
  
  <pre><code>L"Item cannot be found in the collection corresponding to the requested name or ordinal."
  </code></pre>
  
  <p>with an <code>HRESULT</code> of <code>0x800a0cc1</code>.</p>
  
  <p>In both cases I am using a standard ADO recordset object defined as;</p>
  
  <pre><code>_RecordsetPtr       m_pRecordSet;   // recordset object
  </code></pre>
  
  <p>In the MFC version, the function to update the current row in the recordset is:</p>
  
  <pre><code>HRESULT CDBrecordset::UpdateRow(const COleVariant vPutFields, COleVariant vValues)
  {
      m_hr = 0;
      if (IsOpened()) {
          try {
              m_hr = m_pRecordSet-&gt;Update(vPutFields, vValues);
          }
          catch (_com_error &amp;e) {
              _bstr_t bstrSource(e.Description());
              TCHAR *description;
              description = bstrSource;
              TRACE2("  _com_error CDBrecordset::UpdateRow %s  %s\n", e.ErrorMessage(), description);
              m_hr = e.Error();
          }
      }
  
      if (FAILED(m_hr))
          TRACE3(" %S(%d): CDBrecordset::UpdateRow()  m_hr = 0x%x\n", __FILE__, __LINE__, m_hr);
      return  m_hr;
  }
  </code></pre>
  
  <p>This function is called by using two <code>COleSafeArray</code> objects composed into a helper class to make it easier to specify the column names and values to be updated.</p>
  
  <pre><code>// Create my connection string and specify the target database in it.
  // Then connect to SQL Server and get access to the database for the following actions.
  CString  ConnectionString;
  ConnectionString.Format(pConnectionStringTemp, csDatabaseName);
  
  CDBconnector x;
  x.Open(_bstr_t(ConnectionString));
  
  // Create a recordset object so that we can pull the table data that we want.
  CDBrecordset y(x);
  
  //  ....... open and reading of record set deleted.
  
  MyPluOleVariant thing(2);
  
  thing.PushNameValue (SQLVAR_TOTAL, prRec.lTotal);
  thing.PushNameValue (SQLVAR_COUNTER, prRec.lCounter);
  
  hr = y.UpdateRow(thing.saFields, thing.saValues);
  </code></pre>
  
  <p>Because the Windows Console version is not using MFC, I am running into some definition issues which appear to be due to ATL COM class <code>CComSafeArray</code> being a template.</p>
  
  <p>In the MFC source, <code>COleSafeArray</code> is a class derived from <code>tagVARIANT</code> which is a <code>union</code> that is the data structure for a <code>VARIANT</code>. However in ATL COM, <code>CComSafeArray</code> is a template that I am using as <code>CComSafeArray&lt;VARIANT&gt;</code> which seems reasonable.</p>
  
  <p>However when I try to use a variable defined with this template, a class <code>CDBsafeArray</code> derived from <code>CComSafeArray&lt;VARIANT&gt;</code>, I get the following compilation error at the point where I call <code>m_pRecordSet-&gt;Update()</code>:</p>
  
  <pre><code>no suitable user-defined conversion from "const CDBsafeArray" to "const _variant_t" exists
  </code></pre>
  
  <p><code>_variant_t</code> seems to be a wrapper class for <code>VARIANT</code> and there does not seem to be a conversion path between <code>CComSafeArray&lt;VARIANT&gt;</code> and <code>_variant_t</code> however there is a conversion path between <code>COleSafeArray</code> and <code>_variant_t</code>.</p>
  
  <p>What I have tried is to specify the <code>m_psa</code> member of the class which is a <code>SAFEARRAY</code> of type <code>VARIANT</code> and this compiles however I see the COM exception above when testing the application. Looking in the object with the debugger, the object specifying the fields to be updated appears to be correct.</p>
  
  <p>So it appears I am mixing incompatible classes. What would be a <code>SAFEARRAY</code> wrapper class that will work with <code>_variant_t</code>?</p>