Partager via


ILockBytes::ReadAt

ReadAt lit un nombre spécifique d'octets à partir d'un décalage donné par rapport au début du tableau d'octets.

Syntaxe

HRESULT ReadAt(
ULARGE_INTEGERulOffset,
   void *pv,
   ULONG cb,
   ULONG *pcbRead 
   );

Paramètres

Paramètre

Description

ulOffset [in]

Spécifie le point de départ de la lecture des données par rapport au début du tableau d'octets.

pv [in]

Pointeur vers le tampon dans lequel le tableau d'octets est lu.

cb [in]

Spécifie le nombre d'octets de données à lire à partir du tableau d'octets.

pcbRead [out]

Pointeur vers l'emplacement auquel cette méthode écrit le nombre réel d'octets lus à partir du tableau d'octets. Vous pouvez attribuer à ce pointeur la valeur NULL pour indiquer que ce paramètre ne vous intéresse pas. Dans ce cas, cette méthode ne communique pas le nombre réel d'octets lus.

Valeur de retour

Terme

Définition

NOERROR

La méthode a réussi.

E_UNEXPECTED

L'ensemble de lignes est à l'état zombie.

STG_E_INVALIDPOINTER

Un pointeur transmis n'est pas valide.

Notes

L'exemple suivant montre comment utiliser la méthode ILockBytes::ReadAt pour extraire des données d'objet BLOB (binary large object). Cet exemple lit des données image dans la colonne « Photo » de la table Employees.

L'exemple suivant a été mis à jour pour les plateformes 32 bits et 64 bits. Les types compatibles 64 bits proviennent du fichier d'en-tête natif sqlce_oledb.h. Le fichier d'en-tête natif sqlce_oledb.h est disponible dans le dossier %ProgramFiles%\Microsoft SQL Server Compact Edition\v3.5\Include. Pour plus d'informations, consultez la rubrique d'informations sur OLE DB 64 bits dans le Guide du Programmeur OLE DB sur le site Web Microsoft.

Exemple

// Declarations
HRESULT            hr;
DBBINDING          rgBindings[1];
DBPROP             dbprop[1];
DBPROPSET          dbpropset[1];
DBOBJECT           dbObject;
BYTE               pData[100];   // Buffer for holding ILockBytes pointer.
HROW               rghRows[1];   // Array of row handles obtained from rowset object.
HROW               *prghRows           = rghRows;
BYTE               pBuffer[1000];  // Buffer for holding a chunk of BLOB data.
ULARGE_INTEGER     ulOffset;
DBROWCOUNT         cRows               = 0;
IDBInitialize      *pIDBInitialize     = NULL;        
IDBProperties      *pIDBProperties     = NULL;        
IDBCreateSession   *pIDBCreateSession  = NULL;
IDBCreateCommand   *pIDBCreateCommand  = NULL;
ICommandText       *pICommandText      = NULL;
IAccessor          *pIAccessor         = NULL;
IRowset            *pIRowset           = NULL;
ILockBytes         *pILockBytes        = NULL;
HACCESSOR          hAccessor           = DB_NULL_HACCESSOR;

if (FAILED(hr = CoInitialize(NULL)))
{
    return;
}

VariantInit(&dbprop[0].vValue);        

// Create an instance of the OLE DB Provider.
hr = CoCreateInstance(CLSID_SQLSERVERCE, 0, CLSCTX_INPROC_SERVER,
                IID_IDBInitialize, (void**)&pIDBInitialize);
if(FAILED(hr))
{
    // Send error-specific message and do error handling.
    goto Exit;
}

// Initialize a property with name of the database.
// Open an exsiting database myDatabase.
dbprop[0].dwPropertyID     = DBPROP_INIT_DATASOURCE;
dbprop[0].dwOptions         = DBPROPOPTIONS_REQUIRED;
dbprop[0].vValue.vt         = VT_BSTR;
dbprop[0].vValue.bstrVal = SysAllocString(L"\\windows\\MyDB.sdf");
if(NULL == dbprop[0].vValue.bstrVal)
{
    hr = E_OUTOFMEMORY;
    goto Exit;
}

// Initialize the property set.
dbpropset[0].guidPropertySet = DBPROPSET_DBINIT;
dbpropset[0].rgProperties     = dbprop;
dbpropset[0].cProperties     = sizeof(dbprop)/sizeof(dbprop[0]);

// Set initialization properties.
hr = pIDBInitialize->QueryInterface(IID_IDBProperties, 
                (void **)&pIDBProperties);
if(FAILED(hr))
{
    goto Exit;
}

// Sets properties in data source and initialization property groups.
hr = pIDBProperties->SetProperties(1, dbpropset); 
if(FAILED(hr))
{
    goto Exit;
}

// Initializes a data source object. 
hr = pIDBInitialize->Initialize();
if(FAILED(hr))
{
    goto Exit;
}

// Get the IDBCreateSession interface.
hr = pIDBInitialize->QueryInterface(IID_IDBCreateSession,
    (void**)&pIDBCreateSession);
if (FAILED(hr))
{
    // Send error-specific message and do error handling.
    goto Exit;
}
// Get the interface to create a command.
hr = pIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand,
    (IUnknown**) &pIDBCreateCommand);
if (FAILED(hr))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}


// Create the new command that uses parameters.
hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**) &pICommandText);
if (FAILED(hr))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}

// Specify the command text using parameter markers in query syntax.
// This command will return 1 row and one image column (Photo).
hr = pICommandText->SetCommandText(DBGUID_DBSQL, L"SELECT Photo FROM Employees WHERE \"Employee ID\" = 2");
if (FAILED(hr))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}

hr = pICommandText->Execute(NULL, IID_IRowset, NULL, NULL, (IUnknown**) &pIRowset);
if(FAILED(hr))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}

// Create the acessor object and column specific bindings.

hr = pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor);
if (FAILED(hr))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}

// Create the bindings for the photo (BLOB) column.
dbObject.dwFlags = STGM_READ;
dbObject.iid     = IID_ILockBytes;
rgBindings[0].iOrdinal = 1;
rgBindings[0].obStatus = 0;
rgBindings[0].obLength = rgBindings[0].obStatus + sizeof(DBSTATUS);
rgBindings[0].obValue = rgBindings[0].obLength + sizeof(DBLENGTH);
rgBindings[0].pTypeInfo = NULL;
rgBindings[0].pObject = &dbObject;
rgBindings[0].pBindExt = NULL;
rgBindings[0].dwPart = DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS;
rgBindings[0].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
rgBindings[0].eParamIO = DBPARAMIO_NOTPARAM;
rgBindings[0].cbMaxLen = sizeof(IUnknown*);
rgBindings[0].dwFlags = 0;
rgBindings[0].wType = DBTYPE_IUNKNOWN;
rgBindings[0].bPrecision = 0;
rgBindings[0].bScale = 0;

// Create accessor.
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, 1, rgBindings,
    0, &hAccessor, NULL);
if(FAILED(hr))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}

// Get the first row.
hr = pIRowset->GetNextRows(NULL, 0, 1, &cRows, &prghRows);
if(FAILED(hr) || (0 == cRows))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}

// Get the ILockBytes pointer.
hr = pIRowset->GetData(rghRows[0], hAccessor, pData);
if(FAILED(hr))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}

if(DBSTATUS_S_OK != *(DBSTATUS*)(pData + rgBindings[0].obStatus))
{
    // Send an error-specific message and do error handling.
    goto Exit;
}

// Get the ILockBytes pointer from the buffer.
pILockBytes = *(ILockBytes**)(pData + rgBindings[0].obValue);

// Initialize Offset. 
ulOffset.QuadPart = 0;

// Retrieve data from the interface in chunks. 
// The infinite loop for(;;) will terminate when the ReadAt call fails 
//   or if fewer bytes are returned than were requested. 
for(;;)

{

    ULONG cbRead;

    // Read data at the specified offset.
    hr = pILockBytes->ReadAt(ulOffset, pBuffer, sizeof(pBuffer)-sizeof(WCHAR), 
    &cbRead);

///////////////////////////////////////////////////////////////////////
// Do some useful things here with the chunks of data.
///////////////////////////////////////////////////////////////////////

    if(cbRead < sizeof(pBuffer)-sizeof(WCHAR) || FAILED(hr)) break;

    ulOffset.QuadPart += cbRead;
}

// If more rows need to be read, release the ILockBytes pointer  
//   and row handle here.

Exit: 

// When finished, clear the properties arrays and release interfaces.
// Uninitialize the environment.

return;

Voir aussi

Référence

ILockBytes::SetSize

ILockBytes::Stat

ILockBytes::WriteAt

Autres ressources

ILockBytes (SQL Server Compact)