怪事,我给ASP写的组件执行时没有问题,关闭掉IE页面一会后,会出现Unhandled exception at 0x6bc45fad (mfc42.dll) in DLLHOST.EXE: 0xC0000005: Access violation writing location 0x00000004.问题在:http://expert.csdn.net/Expert/TopicView1.asp?id=1674725
有讨论,但是根据提供的建议修改后,还是有这个问题,那个帖子比较乱了,整理后从新发了这个帖子。调试进去,出现这个问题时候的 Call Stack 如下:
> mfc42.dll!CThreadSlotData::SetValue(int nSlot=1, void * pValue=0x000a1350) Line 304 + 0xb C++
mfc42.dll!CThreadLocalObject::GetData(CNoTrackObject * (void)* pfnCreateObject=0x6bc45e77) Line 410 C++
mfc42.dll!AfxGetModuleState() Line 237 C++
mfc42.dll!AfxGetModuleThreadState() Line 252 + 0x5 C++
mfc42.dll!AfxLockTempMaps() Line 30 C++
mfc42.dll!AfxTermThread(HINSTANCE__ * hInstTerm=0x00000000) Line 292 C++
mfc42.dll!DllMain(HINSTANCE__ * hInstance=0x6bc40000, unsigned long dwReason=3, void * __formal=0x00000000) Line 551 C++
mfc42.dll!_DllMainCRTStartup(void * hDllHandle=0x6bc40000, unsigned long dwReason=3, void * lpreserved=0x00000000) Line 276 C
NTDLL.DLL!77f87fcc()
NTDLL.DLL!77f8a9c7()
KERNEL32.DLL!77e8b0ed()
KERNEL32.DLL!77e88423()
KERNEL32.DLL!77e80573()
OLE32.DLL!77a9471e()
NTDLL.DLL!77fb2598()
KERNEL32.DLL!77e6b2d8()
NTDLL.DLL!77fb2598() 这个asp组件的核心代码如下:STDMETHODIMP CReLogin::ReLogin()
{
CoInitialize(NULL);
HRESULT hr;
m_Info = SysAllocString(L"");
_bstr_t m_LoginIP = GetServerItem("REMOTE_ADDR");
_bstr_t m_LoginInfo = GetServerItem("ALL_HTTP");
_bstr_t m_MainCookieVal = GetCookieItem("ABCDEF","" ); unsigned short * m_SessionID = 0;
CComBSTR SessionUserID = "MemberID";
VARIANT var;
VariantInit (&var);
var.vt = VT_I4;
var.lVal = 0;
hr = m_piSession->put_Value(SessionUserID,var);
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"Session无法负值!!");
return hr;
}
hr = m_piSession->get_SessionID(&m_SessionID);
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"初始化Session失败!!");
return hr;
}
_bstr_t m_Seed = m_SessionID;
BSTR m_Name = ::SysAllocString(L"");
m_Sign = VARIANT_FALSE;
long m_MemberID = 0; NetComIF::ILoginPtr pLogin;
hr = pLogin.CreateInstance("CSDN.NetComInterFace.LoginClass");
if (FAILED(hr))
{
if (hr == REGDB_E_CLASSNOTREG)
{
m_Info = ::SysAllocString(L"REGDB_E_CLASSNOTREG");
}
else if (hr == CLASS_E_NOAGGREGATION)
{
m_Info = ::SysAllocString(L"CLASS_E_NOAGGREGATION");
}
else if (hr == CO_E_CLASSSTRING )
{
m_Info = ::SysAllocString(L"CO_E_CLASSSTRING");
}
else if (hr == REGDB_E_WRITEREGDB )
{
m_Info = ::SysAllocString(L"REGDB_E_WRITEREGDB");
}
else
{
m_Info = ::SysAllocString(L"创建COM对象失败!!");
}
return hr;
}
BSTR newMainCookie,newValiCookie,m_Curr_Info;
VARIANT_BOOL m_Curr_Sign = VARIANT_FALSE;
hr = pLogin->MemberLogin(m_Seed,m_MainCookieVal,m_LoginIP,m_LoginInfo,&m_Curr_Sign,&newMainCookie,&newValiCookie,&m_Curr_Info,&m_MemberID,(BSTR *)&(m_Name));
m_Sign = m_Curr_Sign;
m_Info = m_Curr_Info;
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"ATL登录失败!!");
return hr;
} pLogin.Release();
CoUninitialize(); SetCookieItem("ABCDEF","",newMainCookie);
SetCookieItem("QWERTOP","",newValiCookie);
char buffer[20];
_ltoa(m_MemberID,buffer,10);
SetSessionItem("MemberID",buffer);
SetSessionItem("MemberName",m_Name); SysFreeString(m_Name);
SysFreeString(newMainCookie);
SysFreeString(newValiCookie);
SysFreeString(m_Curr_Info);
return S_OK;
}STDMETHODIMP CReLogin::get_Info(BSTR *pVal)
{
// TODO: Add your implementation code here
*pVal = m_Info;
SysFreeString(m_Info);
return S_OK;
}STDMETHODIMP CReLogin::get_Sign(VARIANT_BOOL *pVal)
{
// TODO: Add your implementation code here
*pVal = m_Sign;
return S_OK;
}
有讨论,但是根据提供的建议修改后,还是有这个问题,那个帖子比较乱了,整理后从新发了这个帖子。调试进去,出现这个问题时候的 Call Stack 如下:
> mfc42.dll!CThreadSlotData::SetValue(int nSlot=1, void * pValue=0x000a1350) Line 304 + 0xb C++
mfc42.dll!CThreadLocalObject::GetData(CNoTrackObject * (void)* pfnCreateObject=0x6bc45e77) Line 410 C++
mfc42.dll!AfxGetModuleState() Line 237 C++
mfc42.dll!AfxGetModuleThreadState() Line 252 + 0x5 C++
mfc42.dll!AfxLockTempMaps() Line 30 C++
mfc42.dll!AfxTermThread(HINSTANCE__ * hInstTerm=0x00000000) Line 292 C++
mfc42.dll!DllMain(HINSTANCE__ * hInstance=0x6bc40000, unsigned long dwReason=3, void * __formal=0x00000000) Line 551 C++
mfc42.dll!_DllMainCRTStartup(void * hDllHandle=0x6bc40000, unsigned long dwReason=3, void * lpreserved=0x00000000) Line 276 C
NTDLL.DLL!77f87fcc()
NTDLL.DLL!77f8a9c7()
KERNEL32.DLL!77e8b0ed()
KERNEL32.DLL!77e88423()
KERNEL32.DLL!77e80573()
OLE32.DLL!77a9471e()
NTDLL.DLL!77fb2598()
KERNEL32.DLL!77e6b2d8()
NTDLL.DLL!77fb2598() 这个asp组件的核心代码如下:STDMETHODIMP CReLogin::ReLogin()
{
CoInitialize(NULL);
HRESULT hr;
m_Info = SysAllocString(L"");
_bstr_t m_LoginIP = GetServerItem("REMOTE_ADDR");
_bstr_t m_LoginInfo = GetServerItem("ALL_HTTP");
_bstr_t m_MainCookieVal = GetCookieItem("ABCDEF","" ); unsigned short * m_SessionID = 0;
CComBSTR SessionUserID = "MemberID";
VARIANT var;
VariantInit (&var);
var.vt = VT_I4;
var.lVal = 0;
hr = m_piSession->put_Value(SessionUserID,var);
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"Session无法负值!!");
return hr;
}
hr = m_piSession->get_SessionID(&m_SessionID);
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"初始化Session失败!!");
return hr;
}
_bstr_t m_Seed = m_SessionID;
BSTR m_Name = ::SysAllocString(L"");
m_Sign = VARIANT_FALSE;
long m_MemberID = 0; NetComIF::ILoginPtr pLogin;
hr = pLogin.CreateInstance("CSDN.NetComInterFace.LoginClass");
if (FAILED(hr))
{
if (hr == REGDB_E_CLASSNOTREG)
{
m_Info = ::SysAllocString(L"REGDB_E_CLASSNOTREG");
}
else if (hr == CLASS_E_NOAGGREGATION)
{
m_Info = ::SysAllocString(L"CLASS_E_NOAGGREGATION");
}
else if (hr == CO_E_CLASSSTRING )
{
m_Info = ::SysAllocString(L"CO_E_CLASSSTRING");
}
else if (hr == REGDB_E_WRITEREGDB )
{
m_Info = ::SysAllocString(L"REGDB_E_WRITEREGDB");
}
else
{
m_Info = ::SysAllocString(L"创建COM对象失败!!");
}
return hr;
}
BSTR newMainCookie,newValiCookie,m_Curr_Info;
VARIANT_BOOL m_Curr_Sign = VARIANT_FALSE;
hr = pLogin->MemberLogin(m_Seed,m_MainCookieVal,m_LoginIP,m_LoginInfo,&m_Curr_Sign,&newMainCookie,&newValiCookie,&m_Curr_Info,&m_MemberID,(BSTR *)&(m_Name));
m_Sign = m_Curr_Sign;
m_Info = m_Curr_Info;
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"ATL登录失败!!");
return hr;
} pLogin.Release();
CoUninitialize(); SetCookieItem("ABCDEF","",newMainCookie);
SetCookieItem("QWERTOP","",newValiCookie);
char buffer[20];
_ltoa(m_MemberID,buffer,10);
SetSessionItem("MemberID",buffer);
SetSessionItem("MemberName",m_Name); SysFreeString(m_Name);
SysFreeString(newMainCookie);
SysFreeString(newValiCookie);
SysFreeString(m_Curr_Info);
return S_OK;
}STDMETHODIMP CReLogin::get_Info(BSTR *pVal)
{
// TODO: Add your implementation code here
*pVal = m_Info;
SysFreeString(m_Info);
return S_OK;
}STDMETHODIMP CReLogin::get_Sign(VARIANT_BOOL *pVal)
{
// TODO: Add your implementation code here
*pVal = m_Sign;
return S_OK;
}
解决方案 »
- 请教怎么提高csdn下载需要的那个积分啊~~~ 我的积分为0了
- VS2010的一个小BUG
- GetCurrentProcess()与Process32next()
- 拖动窗口时的残影问题
- 关于vc打补丁的问题。
- ComBoBox控件如何对data中的数据进行排序
- 关于窗体句柄,在线等待,急急急
- 请高手们指点迷津!!
- 求<<深度探索c++对象模型>>一书,或者下载链接.高分回报!
- 请教window局域网访问共享文件的协议!!
- 求助!!!谁知道什么地方有vc技术内幕第四版和深入浅出mfc的电子版下载
- 痛苦,我写的asp组件执行过后某一时间会报dllhost.exe 某某内存地址不能写。但有时候就不报
_bstr_t CReLogin::GetCookieItem(_bstr_t bstrKey, _bstr_t bstrName)
{
VARIANT vtCookieKey;
VariantInit(&vtCookieKey);
vtCookieKey.bstrVal = bstrKey;
vtCookieKey.vt = VT_BSTR; CComPtr<IRequestDictionary> piDict;
HRESULT hr = m_piRequest->get_Cookies(&piDict);
if(FAILED(hr))
{
_bstr_t ret("Error");
return ret.copy();
}
VARIANT vtCookieDict;
VariantInit(&vtCookieDict); hr = piDict->get_Item(vtCookieKey, &vtCookieDict);
if(FAILED(hr))
{
_bstr_t ret("Error");
return ret.copy();
} VARIANTARG varDest;
VariantInit(&varDest);
if (!bstrName.length())
{
hr = VariantChangeType(&varDest, &vtCookieDict, 0, VT_BSTR);
if (FAILED(hr))
{
_bstr_t ret("Error");
return ret.copy();
}
}
else
{
CComPtr<IReadCookie> piReadCookie = (IReadCookie*)(vtCookieDict.pdispVal);
VARIANT vtCookieName;
VariantInit(&vtCookieName);
vtCookieName.bstrVal = bstrName;
vtCookieName.vt = VT_BSTR; VARIANTARG vRet;
VariantInit(&vRet);
piReadCookie->get_Item(vtCookieName, &vRet);
hr = VariantChangeType(&varDest, &vRet, 0, VT_BSTR);
if (FAILED(hr))
{
_bstr_t ret("Error");
return ret.copy();
} }
_bstr_t bstrRet2(varDest.bstrVal);
return bstrRet2.copy();
}_bstr_t CReLogin::GetServerItem(_bstr_t bstrParam)
{
CComPtr<IRequestDictionary> piDic;
HRESULT hr;
VARIANTARG vParam, vRet; hr = m_piRequest->get_ServerVariables(&piDic);
if(FAILED(hr))
{
_bstr_t ret("Error");
return ret.copy();
} ::VariantInit(&vParam);
vParam.vt = VT_BSTR;
vParam.bstrVal = bstrParam; piDic->get_Item(vParam, &vRet); VARIANTARG varDest;
VariantInit(&varDest);
hr = VariantChangeType(&varDest, &vRet, 0, VT_BSTR);
if(FAILED(hr))
{
_bstr_t ret("Error");
return ret.copy();
}
_bstr_t bstrRet1(varDest.bstrVal);
return bstrRet1.copy();}STDMETHODIMP CReLogin::SetCookieItem(_bstr_t bstrKey, _bstr_t bstrName, _bstr_t bstrValue)
{
CComPtr<IRequestDictionary> pDict;
HRESULT hr = m_piResponse->get_Cookies(&pDict);
if(FAILED(hr)) return hr;
VARIANT vtCookieKey;
VariantInit(&vtCookieKey);
vtCookieKey.bstrVal = bstrKey;
vtCookieKey.vt = VT_BSTR; VARIANT vtCookieDict;
VariantInit(&vtCookieDict); hr = pDict->get_Item(vtCookieKey, &vtCookieDict); if(FAILED(hr)) return hr; CComPtr<IWriteCookie> pWriteCookie = (IWriteCookie*)(vtCookieDict.pdispVal); if (!bstrName.length())
{
VARIANT varOptional;
varOptional.vt=VT_ERROR;
varOptional.scode=DISP_E_PARAMNOTFOUND;
return pWriteCookie->put_Item(varOptional, bstrValue);
}
else
{
VARIANT vtCookieName;
VariantInit(&vtCookieName);
vtCookieName.bstrVal = bstrName;
vtCookieName.vt = VT_BSTR;
return pWriteCookie->put_Item(vtCookieName, bstrValue);
}
}STDMETHODIMP CReLogin::SetSessionItem(_bstr_t bstrName, _bstr_t bstrValue)
{
VARIANTARG vValue;
BSTR strName = bstrName; ::VariantInit(&vValue);
vValue.vt = VT_BSTR;
vValue.bstrVal = bstrValue; return m_piSession->put_Value(strName, vValue);}另外:pLogin.CreateInstance("CSDN.NetComInterFace.LoginClass"); 这里调用的是.net 写的组件,然后用regasm 转为类型库。本人对Com 不熟悉,希望大家帮忙找到问题所在。
STDMETHODIMP CReLogin::ReLogin()有一行忘了注释掉了: 正确的应该是://pLogin.Release();
CoUninitialize();不过这样仍然有这个问题.出错提示完全一样.
STDMETHODIMP CReLogin::SetSessionItem(_bstr_t bstrName, _bstr_t bstrValue)
{
VARIANTARG vValue;
BSTR strName = bstrName; ::VariantInit(&vValue);
vValue.vt = VT_BSTR;
vValue.bstrVal = bstrValue; HRESULT resPutValue = m_piSession->put_Value(strName, vValue);
SysFreeString(strName);
return resPutValue;
}
{
.....
}
CoUninitialize();
方式,代码如下,出现的问题更希奇了:STDMETHODIMP CReLogin::ReLogin()
{
CoInitialize(NULL);
{
HRESULT hr;
m_Info = SysAllocString(L"");
_bstr_t m_LoginIP = GetServerItem("REMOTE_ADDR");
_bstr_t m_LoginInfo = GetServerItem("ALL_HTTP");
_bstr_t m_MainCookieVal = GetCookieItem("ABCDEF","" ); unsigned short * m_SessionID = 0;
CComBSTR SessionUserID = "MemberID";
VARIANT var;
VariantInit (&var);
var.vt = VT_I4;
var.lVal = 0;
hr = m_piSession->put_Value(SessionUserID,var);
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"Session无法负值!!");
return hr;
}
hr = m_piSession->get_SessionID(&m_SessionID);
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"初始化Session失败!!");
return hr;
}
_bstr_t m_Seed = m_SessionID;
BSTR m_Name = ::SysAllocString(L"");
m_Sign = VARIANT_FALSE;
long m_MemberID = 0; NetComIF::ILoginPtr pLogin;
hr = pLogin.CreateInstance("CSDN.NetComInterFace.LoginClass");
if (FAILED(hr))
{
if (hr == REGDB_E_CLASSNOTREG)
{
m_Info = ::SysAllocString(L"REGDB_E_CLASSNOTREG");
}
else if (hr == CLASS_E_NOAGGREGATION)
{
m_Info = ::SysAllocString(L"CLASS_E_NOAGGREGATION");
}
else if (hr == CO_E_CLASSSTRING )
{
m_Info = ::SysAllocString(L"CO_E_CLASSSTRING");
}
else if (hr == REGDB_E_WRITEREGDB )
{
m_Info = ::SysAllocString(L"REGDB_E_WRITEREGDB");
}
else
{
m_Info = ::SysAllocString(L"创建COM对象失败!!");
}
return hr;
}
BSTR newMainCookie,newValiCookie,m_Curr_Info;
VARIANT_BOOL m_Curr_Sign = VARIANT_FALSE;
hr = pLogin->MemberLogin(m_Seed,m_MainCookieVal,m_LoginIP,m_LoginInfo,&m_Curr_Sign,&newMainCookie,&newValiCookie,&m_Curr_Info,&m_MemberID,(BSTR *)&(m_Name));
m_Sign = m_Curr_Sign;
m_Info = m_Curr_Info;
if (FAILED(hr))
{
m_Info = ::SysAllocString(L"ATL登录失败!!");
return hr;
}
SetCookieItem("ABCDEF","",newMainCookie);
SetCookieItem("QWERTOP","",newValiCookie); char buffer[20];
_ltoa(m_MemberID,buffer,10);
SetSessionItem("MemberID",buffer);
SetSessionItem("MemberName",m_Name); SysFreeString(m_Name);
SysFreeString(newMainCookie);
SysFreeString(newValiCookie);
SysFreeString(m_Curr_Info);
}
CoUninitialize();
return S_OK;
}新的页面请求会变成:
HTTP/1.1 新建会话失败
HTTP/1.1 500 Server Error Server: Microsoft-IIS/5.0 Date: Sat, 19 Apr 2003 07:26:23 GMT Connection: close Content-Type: text/html Content-Length: 94 Invalid access to memory location. 出错的Call stack为:
> NTDLL.DLL!77fc8d43()
NTDLL.DLL!77fb2616()
NTDLL.DLL!77fc9682()
OLE32.DLL!77a8aa17()
KERNEL32.DLL!77e89872()
comsvcs.dll!6ae3862e()
comsvcs.dll!6ae3832d()
OLE32.DLL!77a880aa()
NTDLL.DLL!77fb2598()
rpcrt4.dll!787538cf()
rpcrt4.dll!78753c1c()
OLE32.DLL!77a46c96()
OLE32.DLL!77aea3e5()
OLE32.DLL!77a4bcf9()
OLE32.DLL!77aa11c6()
OLE32.DLL!77aa0425()
comsvcs.dll!6ae6e86b()
NTDLL.DLL!77fb2616()
NTDLL.DLL!77fb2616()
NTDLL.DLL!77f8e66d()
NTDLL.DLL!77f8e646()
KERNEL32.DLL!77e89739()
OLE32.DLL!77a4bda9()
OLE32.DLL!77a4bd74()
comsvcs.dll!6ae73ec0()
comsvcs.dll!6ae70270()
comsvcs.dll!6ae72ea5()
comsvcs.dll!6ae6ef57()
comsvcs.dll!6ae72008()
comsvcs.dll!6ae6efac()
comsvcs.dll!6ae71183()
comsvcs.dll!6ae711ad()
NTDLL.DLL!77f89bfd()
KERNEL32.DLL!77e6b2d8()
http://expert.csdn.net/Expert/topic/1674/1674725.xml
justleon(蜗牛) 提供的方法作了修改,但是这个问题还是存在,我怀疑是不是一个bug,组件内调用组件操作的这个问题。Unhandled exception at 0x77fc8d43 in DLLHOST.EXE: 0xC0000005: Access violation writing location 0x77a3363e.
在atl组件中,Relogin中,你主动初始化了一个com环境,CoInitialize,然后释放了这个com环境,是否合适?
俺在调用另外的组件的时候,除非是另外启动一个线程,否则从不调用CoInitialize;
除非有全局com对象,否则也不主动释放COM。完全由atl完成这些工作。
如果没有其他办法,你看看去掉Relogin中的CoInitialize,和CoUninitialize。
在atl组件中,Relogin中,你主动初始化了一个com环境,CoInitialize,然后释放了这个com环境,是否合适?我去掉这两个了,但是还有同样的问题。
下面是idl文件// CSDNLOGIN.idl : IDL source for CSDNLOGIN.dll
//// This file will be processed by the MIDL tool to
// produce the type library (CSDNLOGIN.tlb) and marshalling code.import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(D7538E7D-B2FA-4BA6-996A-AC5FEF6F24EC),
dual,
helpstring("IReLogin Interface"),
pointer_default(unique)
]
interface IReLogin : IDispatch
{
//Standard Server Side Component Methods
HRESULT OnStartPage([in] IUnknown* piUnk);
HRESULT OnEndPage();
[id(1), helpstring("method ReLogin")] HRESULT ReLogin();
[propget, id(2), helpstring("property Info")] HRESULT Info([out, retval] BSTR *pVal);
[propget, id(3), helpstring("property Sign")] HRESULT Sign([out, retval] VARIANT_BOOL *pVal);
};[
uuid(64D925D6-E427-4576-9139-D32599629063),
version(1.0),
helpstring("CSDNLOGIN 1.0 Type Library")
]
library CSDNLOGINLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb"); [
uuid(68276F83-4E10-4BAC-B0CE-58FCD051EDA3),
helpstring("ReLogin Class")
]
coclass ReLogin
{
[default] interface IReLogin;
};
};下面是.h文件
// ReLogin.h : Declaration of the CReLogin#ifndef __RELOGIN_H_
#define __RELOGIN_H_#include "resource.h" // main symbols
#include <asptlb.h> // Active Server Pages Definitions/////////////////////////////////////////////////////////////////////////////
// CReLogin
class ATL_NO_VTABLE CReLogin :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CReLogin, &CLSID_ReLogin>,
public ISupportErrorInfo,
public IDispatchImpl<IReLogin, &IID_IReLogin, &LIBID_CSDNLOGINLib>
{
public:
CReLogin()
{
m_bOnStartPageCalled = FALSE;
}public:DECLARE_REGISTRY_RESOURCEID(IDR_RELOGIN)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CReLogin)
COM_INTERFACE_ENTRY(IReLogin)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);// IReLogin
public:
STDMETHOD(get_Sign)(/*[out, retval]*/ VARIANT_BOOL *pVal);
STDMETHOD(get_Info)(/*[out, retval]*/ BSTR *pVal);
STDMETHOD(ReLogin)();
//Active Server Pages Methods
STDMETHOD(OnStartPage)(IUnknown* IUnk);
STDMETHOD(OnEndPage)();private: VARIANT_BOOL m_Sign;
CComBSTR m_Info;
_bstr_t GetServerItem(_bstr_t bstrParam);
_bstr_t GetCookieItem(_bstr_t bstrKey, _bstr_t bstrName);
STDMETHODIMP SetSessionItem(_bstr_t bstrName, _bstr_t bstrValue);
STDMETHODIMP SetCookieItem(_bstr_t bstrKey, _bstr_t bstrName, _bstr_t bstrValue); CComPtr<IRequest> m_piRequest; //Request Object
CComPtr<IResponse> m_piResponse; //Response Object
CComPtr<ISessionObject> m_piSession; //Session Object
CComPtr<IServer> m_piServer; //Server Object
BOOL m_bOnStartPageCalled; //OnStartPage successful?
};#endif //__RELOGIN_H_
開啟頁面正常,當關閉的時候,IE就提示你那些問題.我們發現問題的原因是應為操作系統所支持的語言環境造成的,具體原因我就不太清楚了.
我們的解決方法:用一台純英文(我想最好是98,因為2000好用了,但不表示98好用)的操作系統下重新把你的控件編譯一次..再拿去用.
CComPtr<IResponse> m_piResponse; //Response Object
CComPtr<ISessionObject> m_piSession; //Session Object
CComPtr<IServer> m_piServer; //Server Object的初始化和释放是在STDMETHOD(OnStartPage)(IUnknown* IUnk) & STDMETHOD(OnEndPage)()中吗?
这些都是vc++6默认处理方式处理的,
如下:
STDMETHODIMP CReLogin::OnStartPage (IUnknown* pUnk)
{
if(!pUnk)
return E_POINTER; CComPtr<IScriptingContext> spContext;
HRESULT hr; // Get the IScriptingContext Interface
hr = pUnk->QueryInterface(IID_IScriptingContext, (void **)&spContext);
if(FAILED(hr))
return hr; // Get Request Object Pointer
hr = spContext->get_Request(&m_piRequest);
if(FAILED(hr))
{
spContext.Release();
return hr;
} // Get Response Object Pointer
hr = spContext->get_Response(&m_piResponse);
if(FAILED(hr))
{
m_piRequest.Release();
return hr;
}
// Get Server Object Pointer
hr = spContext->get_Server(&m_piServer);
if(FAILED(hr))
{
m_piRequest.Release();
m_piResponse.Release();
return hr;
}
// Get Session Object Pointer
hr = spContext->get_Session(&m_piSession);
if(FAILED(hr))
{
m_piRequest.Release();
m_piResponse.Release();
m_piServer.Release();
return hr;
}
m_bOnStartPageCalled = TRUE; m_Sign = VARIANT_FALSE;
m_Info = ::SysAllocString(L""); return S_OK;
}STDMETHODIMP CReLogin::OnEndPage ()
{
m_bOnStartPageCalled = FALSE;
// Release all interfaces
m_piRequest.Release();
m_piResponse.Release();
m_piServer.Release();
m_piSession.Release(); return S_OK;
}
STDMETHOD(OnEndPage)();
代码的详细实现?
{
// TODO: Add your implementation code here
*pVal = m_Info;
SysFreeString(m_Info);
return S_OK;
}
这个实现是有问题的。
*pVal=m_Info,可以达到目的,但,必须很小心使用。因为,客户端可能会释放掉,如果COM还使用的话这个值的话,就无法预知结果。SysFreeString(m_Info);
我就更不明白了。为什么这么做?
你这里释放了,外部程序还要释放一次的,因为有两个引用,肯定会出问题的。
正确的做法是直接把它设置为空,m_pInfo=NULL
或者干脆就不管它,如果你在用户调用get_Info之后不再使用这个变量的话
// Get Server Object Pointer
hr = spContext->get_Server(&m_piServer);
if(FAILED(hr))
{
m_piRequest.Release();
m_piResponse.Release();
return hr;
}
m_piServer.AddRef();
...
试试, CComPtr<IRequest> m_piRequest; //Request Object
CComPtr<IResponse> m_piResponse; //Response Object
CComPtr<ISessionObject> m_piSession; //Session Object
CComPtr<IServer> m_piServer; //Server Object
都要做
對於我剛才提出的問題.看了你的情況可能不是用我那解決方法.其實2000下編譯的.基本上在2000各類機器上都可用...我剛才說的問題有點很明顯,就是編譯的時候用了不同的語言dll,而MFC好像就是和語言相關...對於你的程序,不從程序考慮.先考慮你的程序用到 漢字 .所以你看看那atl是否支持漢字..
你的處理程序中似乎需要對中文進行處理.假如你這些中文需要通過atl.而atl又僅能處理英文.這個時候就可能產生問題.
有個方法就是用unicode方式.同時看看那atl是否有unicode支持
把这个调用
hr = pLogin->MemberLogin(m_Seed,m_MainCookieVal,m_LoginIP,m_LoginInfo,&m_Curr_Sign,&newMainCookie,&newValiCookie,&m_Curr_Info,&m_MemberID,(BSTR *)&(m_Name));屏蔽,手工为返回值赋值,如果问题不出现,证明是这个里边有错误。如果问题还出现,那么就是其他的地方。建议2:
完全屏蔽pLogin相关的段落,检查是否出错。建议3:如果以上步骤都出错,那么就是说和你再次调用的组件没有关系,则检查你的几个辅助的 get/set函数。最简单的判断方法,是在你的get/set函数体中直接赋值,立即返回。如果不出错,再一个个判断到底是那个调用有问题。建议4:如果以上还有错,那么让你的系统relogin直接返回S_OK,判断。出错,问题就在你的几个get_info,get_sign之类的其他函数,或系统向导提供的几个函数了。以上步骤还可以细化的如果,以上都出错,哈哈,重写一个组件,让接口函数立即返回,再测试吧
呵呵:)我感觉就是某个对象的释放资源上出现了问题。可能是重复释放,也可能是无法调用合适的释放环境。
看起来不像是与引用的接口有关
比较可能的是某个COM String 有问题
hr = pLogin->MemberLogin(m_Seed,m_MainCookieVal,m_LoginIP,m_LoginInfo,&m_Curr_Sign,&newMainCookie,&newValiCookie,&m_Curr_Info,&m_MemberID,(BSTR *)&(m_Name));
仍然有问题。
hr = pLogin.CreateInstance("CSDN.NetComInterFace.LoginClass");仍然存在这个问题。
{
// TODO: Add your implementation code here
*pVal = m_Info;
SysFreeString(m_Info);
return S_OK;
}
pVal指向了m_Info地址,可是这块内存却马上释放了
所以pVal和m_Info都成为了野指针了
m_Info = SysAllocString(L"");
分配的内存并没有释放过就重新分配了新的内存
你原来的代码比较令人不理解。STDMETHODIMP CReLogin::SetSessionItem(_bstr_t bstrName, _bstr_t bstrValue)
{
// VARIANTARG vValue;
// BSTR strName = bstrName; ::VariantInit(&vValue);
vValue.vt = VT_BSTR;
vValue.bstrVal = bstrName.Copy(); HRESULT resPutValue = m_piSession->put_Value(strName, vValue);// SysFreeString(strName);
VariantClear(&vValue);
return resPutValue;
}
迷惑...另外,VARIANTARG 和VARIANT 有什么区别?俺不太明白。
我一直对那断代码表示怀疑。
如果用CComBSTR类型,那么应该写为
STDMETHODIMP CReLogin::get_Info(BSTR *pVal)
{
// TODO: Add your implementation code here
*pVal = m_Info.Copy();
// SysFreeString(m_Info);//这句还可以有,但如果不用,析构的时候会自动释放
return S_OK;
}
才合适。
这样,组件析构的时候,会自动清理掉m_Info的资源。
而pVal得到的是一个m_Info的复制。
This method stores a variant in theSession object. If the variant is a COM Automation object, then ASP will attempt to store the default value of that object into the application. If ASP cannot get the default value, then the call will fail.HRESULT put_Value(
BSTR bstrValue, //binary string that contains the variable name
VARIANT var //VARIANT that contains the variable value
);
Parameters
bstrValue
A binary string that contains the variable name.
var
A variant that contains the variable value. _variant_t( const _bstr_t& bstrSrc ) throw( _com_error );
STDMETHODIMP CReLogin::SetSessionItem(_bstr_t bstrName, _bstr_t bstrValue)
{
return m_piSession->put_Value(strName.copy( ), _variant_t(bstrValue));
}
4、去掉读Session 部分,仍然有这个问题。
5、全部去掉,只剩一个 return S_OK; 没有任何问题。只剩下如下部分的时候,会出问题:
STDMETHODIMP CReLogin::ReLogin()
{
CComBSTR m_Name;
m_Sign = VARIANT_FALSE; CComBSTR newMainCookie,newValiCookie,m_Curr_Info;
VARIANT_BOOL m_Curr_Sign = VARIANT_FALSE; long m_MemberID = 0; m_MemberID = 4807;
newMainCookie = "jRQQHACKtEImZ8WGbYrmNJKxmvE13%2bCSbxEZ5%2fO31XPxCotQfsqJroInQm8VPNLbjbVTVc8jB9E%3d";
newValiCookie = "2054";
m_Name = "ghj1976";
m_Curr_Sign = VARIANT_TRUE;
m_Curr_Info = ""; m_Sign = m_Curr_Sign;
m_Info = m_Curr_Info; return S_OK;
}其中:下面两个变量是该类的私有变量:
VARIANT_BOOL m_Sign;
CComBSTR m_Info;所有的其他函数都没有变化。
注意m_Info的情况吧。上边有几个帖子是关于它的讨论另外,局部变量为什么要用m前缀呢,和类的成员变量太容易混了。从变量上都看不出来哪个是类的,哪个是函数的临时变量。混乱。代码风格不好。
{
CComBSTR m_Name;
m_Sign = VARIANT_FALSE; CComBSTR newMainCookie,newValiCookie,m_Curr_Info;
VARIANT_BOOL m_Curr_Sign = VARIANT_FALSE; long m_MemberID = 0; m_MemberID = 4807;
newMainCookie = "jRQQHACKtEImZ8WGbYrmNJKxmvE13%2bCSbxEZ5%2fO31XPxCotQfsqJroInQm8VPNLbjbVTVc8jB9E%3d";
newValiCookie = "2054";
m_Name = "ghj1976";
m_Curr_Sign = VARIANT_TRUE;
m_Curr_Info = ""; m_Sign = m_Curr_Sign;
m_Info = m_Curr_Info; return S_OK;
}
has error?
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
把 下面两个函数 改为如下方式,就再也没有这个问题了。STDMETHODIMP CReLogin::get_Info(BSTR *pVal)
{
*pVal = m_Info.Copy();
return S_OK;
}STDMETHODIMP CReLogin::SetSessionItem(_bstr_t bstrName, _bstr_t bstrValue)
{
return m_piSession->put_Value(strName.copy( ), _variant_t(bstrValue));
}非常感谢 zzyx(菜农) 和 zhp80(zhp80)