• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >vc/mfc > 在COM中使用ADO访问SQLSERVER数据库,记录集对象更新数据出错,出错信息“内存已锁定”?

在COM中使用ADO访问SQLSERVER数据库,记录集对象更新数据出错,出错信息“内存已锁定”?

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-04

佚名通过本文主要向大家介绍了 在COM中使用ADO访问SQLSERVER数据库,记录集对象更新数据出错,出错信息“内存已锁定”?等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题: 在COM中使用ADO访问SQL SERVER数据库,记录集对象更新数据出错,出错信息“内存已锁定”?
描述:

我在VC6.0平台下用ATL编写COM组件(没有选择对MFC类库的支持),接口函数UpdateRole(SAFEARRAY **pSaRole),安全数组封装的是自定义的结构体(RoleInfo),以下是组件函数代码,函数可以实现更新数据的目的,但是当调用完成后,返回的不是S_OK,
而是错误码0x8002000d,内存已锁定,如果接口函数传递oleautomation类型的参数不会产生这种错误。我现在是一头雾水,不知道从哪里着手,请高手指点,谢谢!
STDMETHODIMP CSysMgr::UpdateRole(SAFEARRAY **pSaRole)
{
// TODO: Add your implementation code here
USES_CONVERSION;
_bstr_t bstrSQL, bstrRoleID; 
RoleInfo* pRole = NULL;
SafeArrayAccessData(*pSaRole, (void**)&pRole);//从安全数组中取出数据
//nRoleID在结构体中是short类型,先将整型转换为字符型,然后从ANSI编码转换成Unicode编码,
//我本来想用_itow函数,但是不成功,不知道为什么
char ch[5] = "";
itoa(pRole[0].nRoleID, ch, 10);
bstrRoleID = A2BSTR(ch);
// _itow(pRole[0].nRoleID, bstrRoleID, 10);
_bstr_t bstrRoleName = pRole[0].bstrRoleName;
_bstr_t bstrOwner = pRole[0].bstrOwner;
short nRight = pRole[0].nRight;
SafeArrayUnaccessData(*pSaRole);
SafeArrayDestroy(*pSaRole); 
//SQL SERVER数据库表role,主键roleID
bstrSQL = "SELECT * FROM role WHERE roleID = '" + bstrRoleID + "'";
_ConnectionPtr pConnection;
_RecordsetPtr pRecordset;
pConnection.CreateInstance("ADODB.Connection");
pRecordset.CreateInstance(__uuidof(Recordset));
pConnection->Open("DSN=SharePDM3;UID=;PWD=;", "", "", adModeUnknown);//ODBC数据源
pRecordset->Open(bstrSQL, pConnection.GetInterfacePtr(), 
adOpenStatic, adLockOptimistic, adCmdText);
long lNumRecord = pRecordset->RecordCount;
if(lNumRecord != 1)
{
pRecordset->Close();
pConnection->Close();
return E_FAIL;
}
//下面是把数据库字段名和字段值封装到安全数组中
_variant_t varName[3], varValue[3];
varName[0] = L"roleName";
varName[1] = L"owner";
varName[2] = L"accessRight";
varValue[0] = bstrRoleName;
varValue[1] = bstrOwner;
varValue[2] = _variant_t(nRight);
const int nCrit = sizeof(varName) / sizeof(varName[0]);
// Create SafeArray Bounds and initialize the array
SAFEARRAYBOUND rgsaName[1], rgsaValue[1];
rgsaName[0].lLbound = 0;  
rgsaName[0].cElements = nCrit;
SAFEARRAY *psaName = SafeArrayCreate(VT_VARIANT, 1, rgsaName);
rgsaValue[0].lLbound = 0;
rgsaValue[0].cElements = nCrit;
SAFEARRAY *psaValue = SafeArrayCreate(VT_VARIANT, 1, rgsaValue);
// Set the values for each element of the array
HRESULT hr1 = S_OK, hr2 = S_OK;
for( long i = 0 ; i < nCrit && SUCCEEDED(hr1) && SUCCEEDED(hr2);i++)  
{     
hr1 = SafeArrayPutElement(psaName, &i, &varName[i]);
hr2 = SafeArrayPutElement(psaValue, &i, &varValue[i]);
}
  
// Initialize and fill the SafeArray
VARIANT vsaName, vsaValue;  
vsaName.vt = VT_VARIANT | VT_ARRAY;
vsaValue.vt = VT_VARIANT | VT_ARRAY;
V_ARRAY(&vsaName) = psaName;//&vsaName->parray=psaName;
//see definition in oleauto.h file.
V_ARRAY(&vsaValue) = psaValue;
   
hr1 = pRecordset->Update(vsaName, vsaValue);//更新数据
SafeArrayDestroy(psaName);
SafeArrayDestroy(psaValue);
if(FAILED(hr1))
{
pRecordset->Close();
pConnection->Close();
return E_FAIL;
}
pRecordset->Close();
pConnection->Close();
return S_OK;
}
接下来我在MFC编写的客户端程序中调用了UpdateRole方法,代码如下
{
......
SAFEARRAY *pSaRole = SafeArrayCreateEx(...);
//安全数组的定义以及数据的封装
......
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
COSERVERINFO ServerInfo = {0,L"c01",NULL,0};
MULTI_QI MultiQi = {&IID_IUnknown,NULL,NOERROR};
HRESULT hr = CoCreateInstanceEx(CLSID_SysMgr, NULL, CLSCTX_REMOTE_SERVER,
&ServerInfo,1,&MultiQi);
if(FAILED(hr))
{
SafeArrayDestroy(pSaRole);
CoUninitialize();
return FALSE;
}
IUnknown* pUnknown;
pUnknown = (IUnknown*)MultiQi.pItf;
ISysMgr* pSysMgr;
hr = pUnknown->QueryInterface(IID_ISysMgr, (void**)&pSysMgr);
pUnknown->Release();
if(FAILED(hr))
{
SafeArrayDestroy(pSaRole);
CoUninitialize();
return FALSE;
}
hr = pSysMgr->UpdateRole(&pSaRole);//这里调用了COM组件方法,调试时进入(dllhost)组件函数内部单步执行
//可以看到执行了return S_OK语句,但是退出dllhost返回到客户端时,hr值为出错码0x8002000d,内存已锁定,这是什么原因?
pSysMgr->Release();
if(FAILED(hr))
{
SafeArrayDestroy(pSaRole);
CoUninitialize();
return FALSE;
}
......
}


解决方案1:

up

解决方案2:

查看safearray的各个函数哪些会引起锁定。然后研究自己的程序逻辑是否满足了锁定条件。

解决方案3:

最好,先再把代码放入对话框代码中,看代码是否有问题,估计八成问题出在上面

解决方案4:

UP


分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 在COM中使用ADO访问SQLSERVER数据库,记录集对象更新数据出错,出错信息“内存已锁定”?

相关文章

  • 2017-06-04 LPDISPATCH
  • 2017-06-04 ocx控件问题
  • 2017-06-05 用什么钩子才能捕获WM_TIMER消息?
  • 2017-06-05 dll调用时函数参数为函数指针的问题
  • 2017-06-04 关于调用COM+的问题
  • 2017-06-04 activex控件如何往里加编辑筐等控件
  • 2017-06-04 mfc连接MSSQL服务器SA登录失败
  • 2017-06-04 面临择业请高人指点技术难度atl/wtl/流媒体编码/网络编程tcp/ip协议棧
  • 2017-06-04 [请教]计算机中不装MSWord可以在程序中显示和操作doc文档吗?
  • 2017-06-04 问个COM基础问题?

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 急急,页面加载控件时出错,请高手指教
    • 如何用程序将mht格式文件转换为html文件?
    • 求解~~~求大神帮助啊啊啊啊啊
    • VirtualProtect为何失败?
    • 串口类CserialPort的问题,请求帮助。
    • vcMFC的webbrowser2x怎样加载HTML页面里面的activx控件
    • 用ATL怎么实现从本地选择文件上传到服务器?
    • WTL程序中如何打开并按行读取文件?
    • 头文件包含问题
    • 关于在IE中嵌入word的问题!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有