怪事,我给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;
}

解决方案 »

  1.   

    这个组件中还写了几个函数,用于设置、读取Cookie、Session、ServerVariables 这些函数如下:
    _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 不熟悉,希望大家帮忙找到问题所在。
      

  2.   

    最上面的代码
    STDMETHODIMP CReLogin::ReLogin()有一行忘了注释掉了: 正确的应该是://pLogin.Release();
    CoUninitialize();不过这样仍然有这个问题.出错提示完全一样.
      

  3.   

    SetSessionItem 中忘了释放strName 修改一下,但是bug 仍然不在这里,上面提到的bug 仍然存在。
    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;
    }
      

  4.   

    改为:CoInitialize(NULL);
    {
    .....
    }
    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() 
      

  5.   

    to :  qjjz(小人物)  你碰到啥问题了?? 解决了么??
      

  6.   

    我的COM+组件是给客户端的VC程序来调用的,但是在客户端调用后,在服务器上就出现你说的那种提示,经常是竟然地址和你的都一样。
      

  7.   

    今天按照
    http://expert.csdn.net/Expert/topic/1674/1674725.xml
    justleon(蜗牛) 提供的方法作了修改,但是这个问题还是存在,我怀疑是不是一个bug,组件内调用组件操作的这个问题。Unhandled exception at 0x77fc8d43 in DLLHOST.EXE: 0xC0000005: Access violation writing location 0x77a3363e.
      

  8.   

    http://expert.csdn.net/Expert/TopicView1.asp?id=1674725我的所有用vc++6.0 写的代码那里都贴出来了,其他就是用C#写的代码,.net是托管代码,会自动垃圾收集的。
      

  9.   

    依据我的经验是:这种情况一般出现在你的COM中引用了或者导出了一些接口,而在你接收或导出过程中对该接口的计数操作不当,会出现这种情况。你的程序较长,一时不能很好的理解你的CoClass,还是先把你的.idl & .h贴上来,在有针对得去讨论一些执行吧!
      

  10.   

    很象COM环境释放的时机不对。
    在atl组件中,Relogin中,你主动初始化了一个com环境,CoInitialize,然后释放了这个com环境,是否合适?
    俺在调用另外的组件的时候,除非是另外启动一个线程,否则从不调用CoInitialize;
    除非有全局com对象,否则也不主动释放COM。完全由atl完成这些工作。
    如果没有其他办法,你看看去掉Relogin中的CoInitialize,和CoUninitialize。
      

  11.   

    to: zzyx(菜农)
    在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_
      

  12.   

    被调用的组件是.net写的,没有这些文件。
      

  13.   

    我是不會去看你的代碼的.看不懂呀看不懂~~~有過這樣的一個問題,我們原來在做一個攝像頭的ocx網頁控件的時候,也出現和你一樣的問題.
    開啟頁面正常,當關閉的時候,IE就提示你那些問題.我們發現問題的原因是應為操作系統所支持的語言環境造成的,具體原因我就不太清楚了.
    我們的解決方法:用一台純英文(我想最好是98,因為2000好用了,但不表示98好用)的操作系統下重新把你的控件編譯一次..再拿去用.
      

  14.   

    to:YP2002CN(老婆我不敢了,老婆我愛你) 我的整个使用、开发环境都是win2000下完成的。(打了最新补丁包的)
      

  15.   

    STDMETHOD(OnStartPage)(IUnknown* IUnk) & STDMETHOD(OnEndPage)() code? CComPtr<IRequest> m_piRequest; //Request Object
    CComPtr<IResponse> m_piResponse; //Response Object
    CComPtr<ISessionObject> m_piSession; //Session Object
    CComPtr<IServer> m_piServer; //Server Object的初始化和释放是在STDMETHOD(OnStartPage)(IUnknown* IUnk) & STDMETHOD(OnEndPage)()中吗?
      

  16.   

    to: zhp80(zhp80) 
    这些都是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;
    }
      

  17.   

    STDMETHOD(OnStartPage)(IUnknown* IUnk);
    STDMETHOD(OnEndPage)();
    代码的详细实现?
      

  18.   

    to :  zzyx(菜农)  上面倒数第三个回复有实现代码,这部分是vc6默认生成的,我没有修改过这两个函数。
      

  19.   

    to: ndy_w(carpe diem)  那你实现这个功能用啥呀,我自认水平不高,找不到更好的版本。
      

  20.   

    发现一个问题,也许有关系!STDMETHODIMP CReLogin::get_Info(BSTR *pVal)
    {
    // 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之后不再使用这个变量的话
      

  21.   

    to:  zzyx(菜农)  谢谢指出,最初m_Info是BSTR,那里给释放掉,后来改为CComBSTR 忘了修改那里了。不过出现这个错误不在那里,dllhost.exe 内存地址不能读的问题仍然存在。
      

  22.   

    spContext是谁写的?它的 get_Server(&m_piServer)重视增加了引用计数?如是个人做的COM,他有可能遗漏了AddRef改成
    // 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
    都要做
      

  23.   

    CComPtr<IScriptingContext> spContext;这里的代码都是创建atl中的Asp 组件 选择支持asp的 session application request Response Server 自动出现的代码,不是个人写的。而这些Com对象都是iis自己的。
      

  24.   

    想法二
    對於我剛才提出的問題.看了你的情況可能不是用我那解決方法.其實2000下編譯的.基本上在2000各類機器上都可用...我剛才說的問題有點很明顯,就是編譯的時候用了不同的語言dll,而MFC好像就是和語言相關...對於你的程序,不從程序考慮.先考慮你的程序用到 漢字 .所以你看看那atl是否支持漢字..
      

  25.   

    to:YP2002CN我自己的机子是中文版win2000  atl 是英文版的vc6开发的,(没听说过有中文版的vc6)其中用到的组件是vs.net 2003 英文版 c#开发的。
      

  26.   

    我的意思是:
    你的處理程序中似乎需要對中文進行處理.假如你這些中文需要通過atl.而atl又僅能處理英文.這個時候就可能產生問題.
    有個方法就是用unicode方式.同時看看那atl是否有unicode支持
      

  27.   

    如果你有时间,可以简单地分类定位到底是什么引起了错误。建议1:
    把这个调用
    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之类的其他函数,或系统向导提供的几个函数了。以上步骤还可以细化的如果,以上都出错,哈哈,重写一个组件,让接口函数立即返回,再测试吧
    呵呵:)我感觉就是某个对象的释放资源上出现了问题。可能是重复释放,也可能是无法调用合适的释放环境。
      

  28.   

    我也感觉是某个对象的释放资源上出现了问题
    看起来不像是与引用的接口有关
    比较可能的是某个COM String 有问题
      

  29.   

    糊涂了,没想到去掉代码一步步测试这种最古老的方式,正在这么做.1、去掉调用
    hr = pLogin->MemberLogin(m_Seed,m_MainCookieVal,m_LoginIP,m_LoginInfo,&m_Curr_Sign,&newMainCookie,&newValiCookie,&m_Curr_Info,&m_MemberID,(BSTR *)&(m_Name));
    仍然有问题。
      

  30.   

    2、去掉 组件调用所有部分:
    hr = pLogin.CreateInstance("CSDN.NetComInterFace.LoginClass");仍然存在这个问题。
      

  31.   

    STDMETHODIMP CReLogin::get_Info(BSTR *pVal)
    {
    // TODO: Add your implementation code here
    *pVal = m_Info;
    SysFreeString(m_Info);
    return S_OK;
    }
    pVal指向了m_Info地址,可是这块内存却马上释放了
    所以pVal和m_Info都成为了野指针了
      

  32.   

    而且
    m_Info = SysAllocString(L""); 
    分配的内存并没有释放过就重新分配了新的内存
      

  33.   

    问题很可能处在SetSessionItem()上,可以向zzyx(菜农)说的那样先用常量试试
      

  34.   

    SetSessionItem改为如下看看:
    你原来的代码比较令人不理解。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;
    }
      

  35.   

    上个帖子中把VARIANTARG vValue;也注释掉了,应该保留。VariantClear会自动释放其内部的BSTR,所以不用额外调用SysFreeString。不过,我钢材仔细想了想,你原来的写法应该也不会造成问题的。没有调用VariantClear,但你直接调用了SysFreeString,也不会有问题的。
    迷惑...另外,VARIANTARG 和VARIANT 有什么区别?俺不太明白。
      

  36.   

    比较赞同 progame() 说的。
    我一直对那断代码表示怀疑。
    如果用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的复制。
      

  37.   

    ISessionObject::put_Value
    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));
    }
      

  38.   

    3、去掉写Cookie Session 部分,仍然有这个问题。
    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;所有的其他函数都没有变化。
      

  39.   

    哈哈,至少证明和atl调用C#组件没有关系了:)
    注意m_Info的情况吧。上边有几个帖子是关于它的讨论另外,局部变量为什么要用m前缀呢,和类的成员变量太容易混了。从变量上都看不出来哪个是类的,哪个是函数的临时变量。混乱。代码风格不好。
      

  40.   

    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;
    }
    has error?
    ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
      

  41.   

    thanks 已经解决了这个问题:
    把 下面两个函数 改为如下方式,就再也没有这个问题了。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)
      

  42.   

    补充一点: 对各位的帮助非常感谢,尤其是:zhp80(zhp80)、zzyx(菜农)、 progame() 、YP2002CN()  这四位的帮助,下面揭帖。