I just did this in a project myself. What I had to do was Create the DB field as an "OLE Object" (field type). To read/write the field I used a SafeArray packed in a COleVariant (vt = VT_ARRAY | VT_UI1).
Heres some example code:
#import "msado27.tlb" no_namespace \
rename("EOF", "EndOfFile") \
rename("Connection", "ADOConnection") \
rename("Recordset", "ADORecordset")
CString g_cstrDBCon = _T("Driver={Microsoft Access Driver (*.mdb)};Dbq=Test.mdb;Uid=;Pwd=;");
#define __DBCLOSE(AdoObj) { \
if(AdoObj) { \
if(AdoObj->State == adStateOpen) \
AdoObj->Close(); \
AdoObj.Release(); \
AdoObj = NULL; \
} \
}
BOOL Load()
{
BOOL bRetVal = FALSE;
HRESULT hr = NOERROR;
COleVariant cvFieldVal;
CString cstrSQL = _T("");
CString cstrDBError = _T("");
_ConnectionPtr pCn = NULL;
_RecordsetPtr pRs = NULL;
try
{
if(FAILED(hr = pCn.CreateInstance(__uuidof(ADOConnection))))
_com_issue_error(hr);
if(FAILED(hr = pRs.CreateInstance(__uuidof(ADORecordset))))
_com_issue_error(hr);
if(FAILED(pCn->Open(_bstr_t(g_cstrDBCon), "", "", adConnectUnspecified)))
_com_issue_error(hr);
pRs->Open(_bstr_t(L"TableName"), _variant_t((IDispatch*)pCn, true),
adOpenDynamic, adLockPessimistic, adCmdTable);
while(!pRs->EndOfFile)
{
cvFieldVal = pRs->Fields->GetItem(_bstr_t(L"ID"))->GetValue();
long lID = cvFieldVal.lVal;
cvFieldVal = pRs->Fields->GetItem(_bstr_t(L"Name"))->GetValue();
CString cstrName = cvFieldVal.bstrVal;
cvFieldVal = pRs->Fields->GetItem(_bstr_t(L"BinaryValue"))->GetActualSize();
long lActSize = cvFieldVal.lVal;
cvFieldVal = pRs->Fields->GetItem(_bstr_t(L"BinaryValue"))->GetChunk(pNewProp->m_lDefValLen);
if(cvFieldVal.vt == (VT_ARRAY|VT_UI1))
{
BYTE* pBinaryData = new BYTE[lActSize];
char* pBuf = NULL;
SafeArrayAccessData(cvFieldVal.parray, (void**)&pBuf);
memcpy(pBinaryData, pBuf, lActSize);
SafeArrayUnaccessData(cvFieldVal.parray);
delete [] pBinaryData;
}
pRs->MoveNext();
}
pRs->Close();
bRetVal = TRUE;
}
catch(_com_error& e)
{
if((pCn) && (pCn->Errors->Count > 0))
{
ErrorPtr pErr = pCn->Errors->GetItem(0);
cstrDBError.Format(L"Error %x: %s", pErr->Number, (LPWSTR)pErr->Description);
pCn->Errors->Clear();
}
else
{
cstrDBError.Format(L"Error %x: %s", e.Error(), (LPWSTR)e.Description());
}
}
catch(...)
{
cstrDBError = L"Unknown Error";
}
__DBCLOSE(pRs);
__DBCLOSE(pCn);
if(!bRetVal)
{
MessageBox(cstrDBError, _T("DB Error"), MB_ICONERROR);
}
return bRetVal;
}
BOOL Save()
{
BOOL bRetVal = FALSE;
HRESULT hr = NOERROR;
COleVariant cvFieldVal;
CString cstrSQL = _T("");
CString cstrFilter = _T("");
CString cstrDBError = _T("");
_ConnectionPtr pCn = NULL;
_RecordsetPtr pRs = NULL;
try
{
if(FAILED(hr = pCn.CreateInstance(__uuidof(ADOConnection))))
_com_issue_error(hr);
if(FAILED(hr = pRs.CreateInstance(__uuidof(ADORecordset))))
_com_issue_error(hr);
if(FAILED(pCn->Open(_bstr_t(g_cstrDBCon), "", "", adConnectUnspecified)))
_com_issue_error(hr);
long lRecordID = 1;
cstrFilter.Format(L"ID=%d", lRecordID);
pRs->put_Filter(COleVariant(cstrFilter, VT_BSTR));
CString cstrVal = _T("Some Text");
pRs->Fields->GetItem(_bstr_t(L"Name"))->put_Value(COleVariant(cstrVal, VT_BSTR));
long lBinaryValLen = 333;
BYTE* pValue = new BYTE[lBinaryValLen];
memset(pValue, 1, lBinaryValLen);
SAFEARRAYBOUND sab[1];
sab[0].lLbound = 0;
sab[0].cElements = lBinaryValLen;
SAFEARRAY FAR* psa = SafeArrayCreate(VT_UI1, 1, sab);
BYTE* pByte;
if(SafeArrayAccessData(psa, (void**)&pByte) == NOERROR)
memcpy(pByte, pProp->m_pDefValue, pProp->m_lDefValLen);
SafeArrayUnaccessData(psa);
VARIANT vArray;
VariantInit(&vArray);
vArray.vt = VT_ARRAY|VT_UI1;
vArray.parray = psa;
if(FAILED(pRs->Fields->GetItem(_bstr_t(L"BinaryValue"))->AppendChunk(vArray)))
_com_issue_error(hr);
VariantClear(&vArray);
SafeArrayDestroy(psa);
pRs->Update();
pRs->Close();
bRetVal = TRUE;
}
catch(_com_error& e)
{
if((pCn) && (pCn->Errors->Count > 0))
{
ErrorPtr pErr = pCn->Errors->GetItem(0);
cstrDBError.Format(L"Error %x: %s", pErr->Number, (LPWSTR)pErr->Description);
pCn->Errors->Clear();
}
else
{
cstrDBError.Format(L"Error %x: %s", e.Error(), (LPWSTR)e.Description());
}
}
catch(...)
{
cstrDBError = _T("Unknown Error");
}
__DBCLOSE(pRs);
__DBCLOSE(pCn);
if(!bRetVal)
{
MessageBox(cstrDBError, _T("DB Error"), MB_ICONERROR);
}
return bRetVal;
}
Good luck