Не вызывается деструктор.
От: Vegost Россия  
Дата: 30.03.05 05:23
Оценка:
Проект создавался как ATL Project.
Для класса компонента, wizard создал примерно такой код:

#ifndef __ALEMAR_H_
#define __ALEMAR_H_

#include "resource.h"       // main symbols
#include <atlctl.h>
#include <exdisp.h>
#include <Mshtml.h>

#include "pgpfunc.h"

/////////////////////////////////////////////////////////////////////////////
// CAlemar
class ATL_NO_VTABLE CAlemar : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public IDispatchImpl<IAlemar, &IID_IAlemar, &LIBID_ALMRCTRLLib>,
    public CComControl<CAlemar>,
    public IPersistStreamInitImpl<CAlemar>,
    public IOleControlImpl<CAlemar>,
    public IOleObjectImpl<CAlemar>,
    public IOleInPlaceActiveObjectImpl<CAlemar>,
    public IViewObjectExImpl<CAlemar>,
    public IOleInPlaceObjectWindowlessImpl<CAlemar>,
    public CComCoClass<CAlemar, &CLSID_Alemar>,
    public IObjectSafetyImpl<CAlemar, INTERFACESAFE_FOR_UNTRUSTED_CALLER 
                          | INTERFACESAFE_FOR_UNTRUSTED_DATA>

{
public:
    CAlemar()
    {
    }


DECLARE_REGISTRY_RESOURCEID(IDR_ALEMAR)

DECLARE_PROTECT_FINAL_CONSTRUCT()


BEGIN_COM_MAP(CAlemar)
    COM_INTERFACE_ENTRY(IAlemar)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IViewObjectEx)
    COM_INTERFACE_ENTRY(IViewObject2)
    COM_INTERFACE_ENTRY(IViewObject)
    COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
    COM_INTERFACE_ENTRY(IOleInPlaceObject)
    COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
    COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
    COM_INTERFACE_ENTRY(IOleControl)
    COM_INTERFACE_ENTRY(IOleObject)
    COM_INTERFACE_ENTRY(IPersistStreamInit)
    COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
    COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()


BEGIN_MSG_MAP(CAlemar)
    CHAIN_MSG_MAP(CComControl<CAlemar>)
    DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// IViewObjectEx
    DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
// IAlemar
public:
     ~CAlemar()
    {
        //Вот сдесь должны освобождать какие-нибудь ресурсы
            // например
            m_Pgp.FreeLib();

    }
    STDMETHOD(GetDoc)(/*[in]*/BSTR bstrAddr);
    STDMETHOD(Decrypt)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(Initialize)();
    STDMETHOD(PostFile)(BSTR FileName, BSTR Request, BYTE iSource);
    STDMETHOD(get_lReadyState)(LONG* pVal);
    STDMETHOD(put_lReadyState)(LONG newVal);

    HRESULT OnDraw(ATL_DRAWINFO& di)
    {
//
        return S_OK;
    }

    char m_strTempPath[_MAX_PATH];
    PGPClass m_Pgp;
};

#endif //__ALEMAR_H_



Так вот, по завершению работы деструктор не вызывается
Так же пытался вставить что-нибудь типа:


virtual ULONG STDMETHODCALLTYPE Release()
{
  //Освобождение ресурсов
  // например
  m_Pgp.FreeLib();
}


ругается что метод Release уже определен
Так все же где освобождать ресурсы?
Re: Не вызывается деструктор.
От: LioLick  
Дата: 30.03.05 05:51
Оценка:
Здравствуйте, Vegost, Вы писали:

V>Так все же где освобождать ресурсы?

Обычно в FinalRelease().
Но есть подозрение что у Вас и он не вызовется, потому как в Вашем случае деструктор должен бы вызываться.
GL!
Re[2]: Не вызывается деструктор.
От: Vegost Россия  
Дата: 30.03.05 07:04
Оценка:
FinalRelease() — ведет себя так-же как и деструктор, т.е никак не вызывается.
Хотя в контроле (функция DllMain) часть связанная с DLL_PROCESS_DETACH
запускается


CComModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_Alemar, CAlemar)
END_OBJECT_MAP()

/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance, &LIBID_ALMRCTRLLib);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {

           _Module.Term();
    }
    return TRUE;    // ok
}


И внутри функции _Module.Term() вызывается Release() для каждого _ATL_OBJMAP_ENTRY
т.е. и для класса CAlemar тоже
Re: Не вызывается деструктор.
От: ssm Россия  
Дата: 30.03.05 07:40
Оценка: +1
Здравствуйте, Vegost, Вы писали:

V>Проект создавался как ATL Project.

V>Для класса компонента, wizard создал примерно такой код:

Нужен клиентский код использования COM объекта, у тебя ИМХО там проблемы
Re[3]: Не вызывается деструктор.
От: Vi2 Удмуртия http://www.adem.ru
Дата: 30.03.05 07:48
Оценка:
Здравствуйте, Vegost, Вы писали:

V>И внутри функции _Module.Term() вызывается Release() для каждого _ATL_OBJMAP_ENTRY т.е. и для класса CAlemar тоже


В _Module.Term() вызываются Release() для всех фабрик классов, а не экземпляров, полученных с помощью этих фабрик.
Единственный класс, который может получить Release() и деструктор, — это ATL синглетон, т.е. в котором есть упоминание DECLARE_CLASSFACTORY_SINGLETON.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Не вызывается деструктор.
От: LioLick  
Дата: 30.03.05 08:39
Оценка:
Здравствуйте, Vegost, Вы писали:

V>FinalRelease() — ведет себя так-же как и деструктор, т.е никак не вызывается.

V>Хотя в контроле (функция DllMain) часть связанная с DLL_PROCESS_DETACH
V>запускается
V>И внутри функции _Module.Term() вызывается Release() для каждого _ATL_OBJMAP_ENTRY
V>т.е. и для класса CAlemar тоже

Это к делу отношения не имеет.
Похоже, у Вас просто где-то утечка ссылок.
GL!
Re[2]: Не вызывается деструктор.
От: Vegost Россия  
Дата: 30.03.05 08:44
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, Vegost, Вы писали:


V>>Проект создавался как ATL Project.

V>>Для класса компонента, wizard создал примерно такой код:

ssm>Нужен клиентский код использования COM объекта, у тебя ИМХО там проблемы



COM-понента вызывается из Internet Explorera
примерно так:

<BODY LANGUAGE="javascript" onload="MyObj.Initiaalize();">

<OBJECT id="MyObj" codeBase="http://webserver/almrctrl.cab#version=1,0,X,X" height="0" width="0" data="data:application/x-oleobject;base64,4El3WSeUYkGhIL8+FRaLYAAHAAAaAAAAGgAAAA==" classid="clsid:597749E0-9427-4162-A120-BF3E15168B60">
</OBJECT>

</BODY>


Ну и соответственно по завершению работы с Explorer'ом вдруг почистить за собой (т.е за PGP Lib)
Re: Не вызывается деструктор.
От: SaloS http://salos.narod.ru/
Дата: 30.03.05 08:50
Оценка:
Здравствуйте, Vegost, Вы писали:

У меня аналогичная проблема. Мой плагин (сгенеренный wizrad'ом) к VS.NET нормально работает, вызывается он, соответсвенно, IDE'шкой и я ничего не меняю. Так вот объект создается, но не удаляется.

V>Проект создавался как ATL Project.

V>Для класса компонента, wizard создал примерно такой код:

V>

V>/////////////////////////////////////////////////////////////////////////////
V>// CAlemar
V>class ATL_NO_VTABLE CAlemar : 
V>    public CComObjectRootEx<CComSingleThreadModel>,
V>    public IDispatchImpl<IAlemar, &IID_IAlemar, &LIBID_ALMRCTRLLib>,
V>    public CComControl<CAlemar>,
V>    public IPersistStreamInitImpl<CAlemar>,
V>    public IOleControlImpl<CAlemar>,
V>    public IOleObjectImpl<CAlemar>,
V>    public IOleInPlaceActiveObjectImpl<CAlemar>,
V>    public IViewObjectExImpl<CAlemar>,
V>    public IOleInPlaceObjectWindowlessImpl<CAlemar>,
V>    public CComCoClass<CAlemar, &CLSID_Alemar>,
V>    public IObjectSafetyImpl<CAlemar, INTERFACESAFE_FOR_UNTRUSTED_CALLER 
V>                          | INTERFACESAFE_FOR_UNTRUSTED_DATA>

V>{
V>public:
V>    CAlemar()
V>    {
V>    }

V>



V>Так вот, по завершению работы деструктор не вызывается

V>Так же пытался вставить что-нибудь типа:


V>
V>virtual ULONG STDMETHODCALLTYPE Release()
V>{
V>  //Освобождение ресурсов
V>  // например
V>  m_Pgp.FreeLib();
V>}
V>


V>ругается что метод Release уже определен

V>Так все же где освобождать ресурсы?
WTL Helper и WTL Wizards помощники для WTL, скачать отсюда http://salos.narod.ru
Re[3]: Не вызывается деструктор.
От: ssm Россия  
Дата: 30.03.05 08:54
Оценка:
Здравствуйте, Vegost, Вы писали:


V>Ну и соответственно по завершению работы с Explorer'ом вдруг почистить за собой (т.е за PGP Lib)


перечитал пять раз, но так и непонял к чему относится "вдруг"
мне вот интерестно, на основании чего сделан вывод о том, что деструктор не вызывается?
и как уже сказали, код для освобождения ресурсов рекомендуется помещать в FinalRelease()
Re[4]: Не вызывается деструктор.
От: Vegost Россия  
Дата: 30.03.05 10:00
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, Vegost, Вы писали:



V>>Ну и соответственно по завершению работы с Explorer'ом вдруг почистить за собой (т.е за PGP Lib)


ssm>перечитал пять раз, но так и непонял к чему относится "вдруг"

Sorry очепятка вышла.
Ну т.е раньше я освобождал ресурсы в нутри вызваемого метода
например в IE вызываю <SCRIPT language="javascript">myObj.GetPrivDoc("")</SCRIPT>
внутри этого метода (GetPrivDoc) работаю с библиотекой PGP
а в конце метода освобождаю ресурсы и все что PGP насоздавала.

А теперь (пресловутый "вдруг") захотелось в начале работы инициализировать PGP,
а по завершению работы с InternetExplorer'ом ее освобождать где-нибудь в деструкторе.
IMHO: так красивее

ssm>мне вот интерестно, на основании чего сделан вывод о том, что деструктор не вызывается?


на основании работы с дебагером. Меню->Debug->Processes->(IE c моей компнентой)
причем в контроле отлично проходит через DLL_PROCESS_DETACH и вызывает
_Module.Term(); который в свою очередm вызывает IUnknown->Release()
для OBJECT_ENTRY(CLSID_Alemar, CAlemar)

ssm>и как уже сказали, код для освобождения ресурсов рекомендуется помещать в FinalRelease()

Обьявлял и Release и FinalRelease причем все компилируется без ошибок, но не вызывает
Re: Проблема решена
От: Vegost Россия  
Дата: 31.03.05 01:33
Оценка:
Все действительно решилось добавлением макроса
DECLARE_CLASSFACTORY_SINGLETON


class ATL_NO_VTABLE CAlemar : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public IDispatchImpl<IAlemar, &IID_IAlemar, &LIBID_ALMRCTRLLib>,
    public CComControl<CAlemar>,
    public IPersistStreamInitImpl<CAlemar>,
    public IOleControlImpl<CAlemar>,
    public IOleObjectImpl<CAlemar>,
    public IOleInPlaceActiveObjectImpl<CAlemar>,
    public IViewObjectExImpl<CAlemar>,
    public IOleInPlaceObjectWindowlessImpl<CAlemar>,
    public CComCoClass<CAlemar, &CLSID_Alemar>,
    public IObjectSafetyImpl<CAlemar, INTERFACESAFE_FOR_UNTRUSTED_CALLER 
                          | INTERFACESAFE_FOR_UNTRUSTED_DATA>

{

public:

DECLARE_CLASSFACTORY_SINGLETON(CAlemar)

    CAlemar()
    {
        m_strTempPath[0]='\0';
    }

    ~CAlemar()
    {
         //освобождение ресурсов
    }


спасибо всем за советы
Re[2]: Проблема решена
От: Vi2 Удмуртия http://www.adem.ru
Дата: 31.03.05 03:22
Оценка:
Здравствуйте, Vegost, Вы писали:

V>class ATL_NO_VTABLE CAlemar : ... public CComControl<CAlemar>, public IOleControlImpl<CAlemar>,
V>...
V>DECLARE_CLASSFACTORY_SINGLETON(CAlemar)


Контрол и синглетон? Что-то ты мудришь на ровном месте.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Проблема решена
От: Vegost Россия  
Дата: 31.03.05 07:17
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, Vegost, Вы писали:


Vi2>
V>>class ATL_NO_VTABLE CAlemar : ... public CComControl<CAlemar>, public IOleControlImpl<CAlemar>,
V>>...
V>>DECLARE_CLASSFACTORY_SINGLETON(CAlemar)
Vi2>


Vi2>Контрол и синглетон? Что-то ты мудришь на ровном месте.


Вот именно в таком виде все компилируруется без ошибок и главное вызвается деструктор
по завершению работы.
А контрол он или не контрол не могу сказать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.