SAndrus
|
|
« : 05-04-2010 17:27 » |
|
Доброе время суток, давно работаю с SQL Server из VC++6 небыло проблем, теперь необходимо сохранить приличный объем данных (32кБ) бинарных данных, и тут косяк, с тем что предлагает студия при создании проекта (там указатель создается), не подключается к базе, как строкой читать из базы получается, а писать в базу никак. Пожалуйста помогите кто знает.
|
|
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 06-04-2010 09:43 » |
|
SAndrus, а код покажи, как тебе подсказывать будут то ?
|
|
|
Записан
|
|
|
|
SAndrus
|
|
« Ответ #3 : 06-04-2010 15:37 » |
|
когда в базе создавал данные varchar[8000], класс интерфейса создавался типа
char mDann[8001]
а интерфейс колонки:
COLUMN_ENTRY_TYPE(1, DBTYPE_STR, m_mDann)
но как понял если бинарный нуль в начале строки то вся строка теряется
пробовал в базе создать varbinary[8000] класс создавался с переменной
ISequentialStream* m_mDann;
интерфейс типа:
BLOB_ENTRY(1, IID_ISequentialStream, STGM_READ, m_mDann)
программа выпадала на инструкции MoveNext при откритии RowSet
|
|
|
Записан
|
|
|
|
SAndrus
|
|
« Ответ #4 : 08-04-2010 07:37 » |
|
подскажите, почему функция: m_pBuffer = CoTaskMemRealloc( m_pBuffer, m_ulLength ); выдает ошибку при попытке выделения 11288 байтов, а при выделении 4096, на первом цикле и 4096*2 на втором цикле считывания все нормально
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 08-04-2010 07:42 » |
|
может быть, нужно освобождать в промежутках - CoTaskMemFree (но не знаю, не пользовался этими функциями)
|
|
|
Записан
|
|
|
|
SAndrus
|
|
« Ответ #6 : 08-04-2010 07:49 » |
|
там, во втором топике ссылка, программа использует этот механизм, заливает до 15 мегов, а я чет неправильно делаю
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #7 : 08-04-2010 07:59 » |
|
SAndrus, код показывай, что тут ещё можно сказать ?
|
|
|
Записан
|
|
|
|
SAndrus
|
|
« Ответ #8 : 08-04-2010 08:12 » |
|
по ссылке это код примера, ISSHelper там функция сохранения :
HRESULT CISSHelper::Write( const void *pv, ULONG cb, ULONG* pcbWritten ) { // Check parameters. if ( !pv ) return STG_E_INVALIDPOINTER; if ( pcbWritten ) *pcbWritten = 0; if ( 0 == cb ) return S_OK;
// Enlarge the current buffer. m_ulLength += cb;
// Grow internal buffer to new size. m_pBuffer = CoTaskMemRealloc( m_pBuffer, m_ulLength );
// Check for out of memory situation. if ( NULL == m_pBuffer ) { Clear(); return E_OUTOFMEMORY; }
memset((void*)((BYTE*)m_pBuffer + m_iWritePos),0,m_ulLength);
// Copy callers memory to internal bufffer and update write position. memcpy( (void*)((BYTE*)m_pBuffer + m_iWritePos), pv, cb ); m_iWritePos += cb;
// Return bytes written to caller. if ( pcbWritten ) *pcbWritten = cb;
return S_OK; }
а это функция считывания из базы тоже практически не изменял:
void LoadLongData() { BYTE rgBuffer[4096]; ULONG ulBytesRead;
HRESULT hr; hr = session.Open( *db ); if ( FAILED(hr) ) { return; }
// Open rowset. This will fail if BLOB1234 table does not exist. hr = OpenRowset(); if ( FAILED(hr) ) { return; }
// Position rowset to first (one and only) record. hr = MoveFirst(); if ( FAILED(hr) ) { return; }
if ( DBSTATUS_S_OK != m_mDann_STATUS ) { return; }
// Read data from blob field. do { // Call ISequentialStream::Read using provider's pointer. hr = m_mDann->Read( rgBuffer, sizeof(rgBuffer), &ulBytesRead ); if ( FAILED(hr) ) { return; }
// Stuff data into helper class which is used as a dynamic buffer here. hr = ISSHelper.Write( rgBuffer, sizeof(rgBuffer), NULL ); if ( FAILED(hr) ) { return; }; } while ( sizeof(rgBuffer) == ulBytesRead ); FreeRecordMemory(); Close(); }
вызываю вот так:
void CLongDannDlg::OnButton1() { UpdateData(); CHndlMagnLDann bas; UINT vNom=m_IDC_EDIT2;HRESULT hr; UINT nom=m_IDC_EDIT1; bas.db=&basa; bas.sSQLgl.Format("select * from mDann where vnom=%d",vNom); bas.LoadLongData(); if(hr!=S_OK)return; BYTE *dn=(BYTE*)bas.ISSHelper.m_pBuffer; if(dn!=0)m_IDC_EDIT3.Format("%d %d %d %d %d",dn[nom],dn[nom+1],dn[nom+2],dn[nom+3],dn[nom+4]); UpdateData(FALSE); }
basa; - открываю при инициализации диалога правда создаю это все на базе диалога, хотя там тоже на диалоге сделано, может настроики какие
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #9 : 08-04-2010 08:20 » |
|
поставь остановку сразу после строки m_pBuffer = CoTaskMemRealloc( m_pBuffer, m_ulLength ); и глянь, что вернёт GetLastError() после возникновения ошибки (или просто идентификатор "err" в просмотре переменных впиши)
|
|
|
Записан
|
|
|
|
SAndrus
|
|
« Ответ #10 : 08-04-2010 08:24 » |
|
и err и GetLastError возвращают 0, при выполнении этой функции в третий раз программа останавливается на ассемблерском коде на пользовательском прерываниии
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #11 : 08-04-2010 08:30 » |
|
int 3 ?
когда у менятакое выскакивало - обычно обнаруживалась порча памяти неким способом )))
Рыться в коде некогда сейчас, может вечером
|
|
|
Записан
|
|
|
|
SAndrus
|
|
« Ответ #12 : 08-04-2010 08:34 » |
|
спасибо, поищу
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 08-04-2010 08:36 » |
|
обрати внимание, какой адрес памяти показывается при глюке - вроде пишется, какой участок памяти портится - по адресу можно вычислить переменную , которая портится или её память
ещё можно скопировать проект и понемногу отключать всё подряд, пока не станет глюка, и там искать.
|
|
|
Записан
|
|
|
|
SAndrus
|
|
« Ответ #14 : 08-04-2010 09:15 » |
|
надо же оказалось что функция:
memset((void*)((BYTE*)m_pBuffer + m_iWritePos),0,m_ulLength);
это безобразие и творит, отключил и ее нормально все выделяет
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 08-04-2010 09:28 » |
|
можно было так записать, но что то у тебя неверно с одной из этих трёх переменных - гляди под отладчиком значения. Может, не инициализарованы
memset(((BYTE*)m_pBuffer)[m_iWritePos],0,m_ulLength);
если всё
|
|
|
Записан
|
|
|
|
SAndrus
|
|
« Ответ #16 : 08-04-2010 10:05 » |
|
ага, разобрался m_ulLength это общая длина пакета, а надо часть которую пишем, исправил спасибо
|
|
|
Записан
|
|
|
|
|