一个比较挠头的AppendChunk问题

yfwill 2005-01-13 06:49:26
//////////////////////////////////////////////////////////////////////////
//将图像空间中图像的数据存储到数据库的image字段上,不包含图像长宽等信息
void SaveBmpToDB()
{

BITMAP bmp;
::GetObject(m_mfc.GetBitmap(), sizeof(BITMAP), &bmp);
//m_mfc为一个CStatic对象,已经绑定到一个图片控件上 DDX_Control(pDX, IDC_STATIC_SOURCE, m_mfc);


//取出图像的数据
BYTE* pBits = new BYTE[bmp.bmWidthBytes*bmp.bmHeight];
LONG lBitsSize = ::GetBitmapBits(m_mfc.GetBitmap(), bmp.bmWidthBytes*bmp.bmHeight, pBits);

if ( 0 == lBitsSize) {
delete[] pBits;
return;
}

HRESULT hr;

_variant_t varChunk;
varChunk.vt = VT_ARRAY | VT_UI1;

//rsImage是一个已经打开的记录及,下面是打开方法 _RecordsetPtr rsImage
//rsImage->Open(_T("Image"),_variant_t((IDispatch*)cnPreH2k),adOpenDynamic,
// adLockOptimistic, adCmdTable);

rsImage->AddNew();


//为了增加存储速度,我采用了将整个数据分段存储

LONG lOffSet = 0; //分段的偏移位置
LONG lPackSize = 56; //分段的长度
LONG lPerLen = lPackSize; //当最后出现剩余长度小于分段长度的时候使用lPerLen
for( ; lOffSet < lBitsSize; lOffSet += lPackSize ){

if ( lOffSet + lPackSize >= lBitsSize ) {//当最后出现剩余长度小于分段长度的时
lPerLen = lBitsSize-lOffSet;
}


SAFEARRAY FAR *psa;
SAFEARRAYBOUND rgsabound[1];

rgsabound[0].lLbound = lOffSet;
rgsabound[0].cElements = lPerLen;
psa = ::SafeArrayCreate(VT_UI1, 1, rgsabound);

BYTE* buf = NULL;
hr = SafeArrayAccessData(psa, (void**)&buf);
if (FAILED(hr)) {
break;
}

//buf是psa的缓冲区
memcpy(buf, pBits+lOffSet, lPerLen);
SafeArrayUnaccessData(psa); //接触对psa的锁定

varChunk.parray = psa;

hr = rsImage->Fields->GetItem("ImageBits")->AppendChunk(varChunk);
if (FAILED(hr)) {
break;
}


////
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
//1.如果有下面SafeArrayDestroy语句,在反复调用这个函数的时候,
//或者在操作rsImage记录集的时候,就会出现异常
//2.如果删掉这个语句,程序不会出现异常,但在反复调用的过程中,内存不被释放
//系统内存占用越来越多
SafeArrayDestroy(psa);

//我们一帮人忙了几天也没弄明白到底为什么?求高手相救


}

rsImage->Update();

delete[] pBits;
}
...全文
128 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
gpib2000 2005-01-20
  • 打赏
  • 举报
回复
我也遇到类似的问题,留个联系方式,讨论一下吧。QQ:30622240
Amyice 2005-01-18
  • 打赏
  • 举报
回复
你删除时可以这样试试:
inline void TESTHR( HRESULT _hr )
{ if FAILED(_hr) _com_issue_error(_hr); }

TESTHR(SafeArrayDestroy(psa));
varChunk.vt = VT_EMPTY;
varChunk.parray = NULL;

SafeArrayDestroy(psa)那句话应该不会报错,但系统内存不知道会不会释放掉!你可以看看我新发的帖子,我试过了好多次,只要循环调用存储代码,过一段时间内存肯定会增长。
llm06 2005-01-14
  • 打赏
  • 举报
回复
通过操作access可以发现,执行SafeArrayDestroy(psa);根本就没有报任何错误。

估计appendchunk比较耗时,而且可能是异步的,在还没有结束时调用safearraydestroy导致出错。不知道是不是这个原因。

搂住可以在access下面试一下。

4,012

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧