--- title: "Visual C++ Extensions Example | Microsoft Docs" ms.prod: sql ms.prod_service: connectivity ms.technology: connectivity ms.custom: "" ms.date: 11/08/2018 ms.reviewer: "" ms.topic: conceptual dev_langs: - "C++" helpviewer_keywords: - "ADO, Visual C++" - "Visual C++ [ADO], VC++ extensions example" ms.assetid: 9739c278-582c-402b-a158-7f68a1b2c293 author: MightyPen ms.author: genemi --- # Visual C++ Extensions Example This program shows how values are retrieved from fields and converted to C/C++ variables. This example also takes advantage of "smart pointers," which automatically handle the COM-specific details of calling `QueryInterface` and reference counting for the **IADORecordBinding** interface. Without smart pointers, you would code: ```cpp IADORecordBinding   *picRs = NULL; ... TESTHR(pRs->QueryInterface( __uuidof(IADORecordBinding), (LPVOID*)&picRs)); ... if (picRs) picRs->Release(); ``` With smart pointers, you derive the `IADORecordBindingPtr` type from the `IADORecordBinding` interface with this statement: ```cpp _COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding)); ``` And instantiate the pointer like this: ```cpp IADORecordBindingPtr picRs(pRs); ``` Because the Visual C++ Extensions are implemented by the **Recordset** object, the constructor for the smart pointer, `picRs`, takes the _`RecordsetPtr` pointer, `pRs`. The constructor calls `QueryInterface` using `pRs` to find the `IADORecordBinding` interface. ```cpp // Visual_Cpp_Extensions_Example.cpp // compile with: /EHsc #import "msado15.dll" no_namespace rename("EOF", "EndOfFile") #include _COM_SMARTPTR_TYPEDEF(IADORecordBinding, __uuidof(IADORecordBinding)); inline void TESTHR(HRESULT _hr) { if FAILED(_hr) _com_issue_error(_hr); } class CCustomRs : public CADORecordBinding { BEGIN_ADO_BINDING(CCustomRs) ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_ch_fname, sizeof(m_ch_fname), m_ul_fnameStatus, false) ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_ch_lname, sizeof(m_ch_lname), m_ul_lnameStatus, false) END_ADO_BINDING() public: CHAR m_ch_fname[22]; CHAR m_ch_lname[32]; ULONG m_ul_fnameStatus; ULONG m_ul_lnameStatus; }; int main() { ::CoInitialize(NULL); try { _RecordsetPtr pRs("ADODB.Recordset"); CCustomRs rs; IADORecordBindingPtr picRs(pRs); pRs->Open(L"SELECT * FROM Employee ORDER BY lname", L"dsn=DataPubs;Trusted_Connection=yes;", adOpenStatic, adLockOptimistic, adCmdText); TESTHR(picRs->BindToRecordset(&rs)); while (!pRs->EndOfFile) { // Process data in the CCustomRs C++ instance variables. printf("Name = %s %s\n", (rs.m_ul_fnameStatus == adFldOK ? rs.m_ch_fname: ""), (rs.m_ul_lnameStatus == adFldOK ? rs.m_ch_lname: "") ); // Move to the next row of the Recordset. Fields in the new row will // automatically be placed in the CCustomRs C++ instance variables. pRs->MoveNext(); } } catch (_com_error &e ) { printf("Error:\n"); printf("Code = %08lx\n", e.Error()); printf("Meaning = %s\n", e.ErrorMessage()); printf("Source = %s\n", (LPCSTR) e.Source()); printf("Description = %s\n", (LPCSTR) e.Description()); } ::CoUninitialize(); } ``` ## See Also [Using Visual C++ Extensions](../../../ado/guide/appendixes/using-visual-c-extensions.md) [Visual C++ Extensions Header](../../../ado/guide/appendixes/visual-c-extensions-header.md)