исчезают интерфейсы
От: 13akaEagle Россия  
Дата: 23.12.10 10:49
Оценка:
Есть несколько интерфейсов

ATL::CComPtr<IOPCGroupStateMgt> iStateManagement;
ATL::CComPtr<IOPCItemMgt> iItemManagement;
COPCServer &opcServer;

далее инициализируем их, всё проходит нормально.

Когда приходит время поюзать методы интерфейсов, то тут возникает облом. Интерфейсы оказываются неинициализрованны, а ссылка opcServer вообще никуда не указывает.

На моём компе, winxp sp3, такого не происходит. Такого не происходит и на виртуальной машине, тоже winxp sp3. Но данная ошибка возникает на другом компе, где сначала стоял winxp sp2. На ещё одном компе winxp sp3, ошибка тоже не проявляется. Подумал я что это из-за sp3 и накатил его на проблемный комп, но проблема не решилась.
Какие будут мысли?

Спасибо.
Re: исчезают интерфейсы
От: 13akaEagle Россия  
Дата: 23.12.10 10:51
Оценка:
Добавлю. Сам указатель this класса, кому принадлежат эти методы указывает на NULL.
Re[2]: исчезают интерфейсы
От: quodum  
Дата: 23.12.10 11:09
Оценка:
Здравствуйте, 13akaEagle, Вы писали:

E>Добавлю. Сам указатель this класса, кому принадлежат эти методы указывает на NULL.


1. Какие "эти методы"? Поточнее с формулировками, если можно. В исходном сообщении ни одного метода не упоминается.
2. Ну, лажа у тебя с управлением времени жизни объектом, this которого ты наблюдаешь равным нулю. Где-то AddRef забыл, или использовал не ту форму инициализации CComPtr. На твоих компах тебе везёт и это не проявляется. Если предположений о том, где такое может быть, нет -- включи _ATL_DEBUG_INTERFACES, собери лог при падении и анализируй...
3. Ещё альтернатива -- расстрел памяти. Попробуй всяческие анализаторы (статические и runtime), вдруг помогут.
Re[3]: исчезают интерфейсы
От: 13akaEagle Россия  
Дата: 24.12.10 03:25
Оценка:
Здравствуйте, quodum, Вы писали:

Q>1. Какие "эти методы"? Поточнее с формулировками, если можно. В исходном сообщении ни одного метода не упоминается.

Q>2. Ну, лажа у тебя с управлением времени жизни объектом, this которого ты наблюдаешь равным нулю. Где-то AddRef забыл, или использовал не ту форму инициализации CComPtr. На твоих компах тебе везёт и это не проявляется. Если предположений о том, где такое может быть, нет -- включи _ATL_DEBUG_INTERFACES, собери лог при падении и анализируй...
Q>3. Ещё альтернатива -- расстрел памяти. Попробуй всяческие анализаторы (статические и runtime), вдруг помогут.

Да, извините, очень коряво написал.
Проблема сдвинулась немного в другую сторону.
Есть такой код:

AddTagFrame.h:

class AddTagFrame : public wxFrame
{
    DECLARE_DYNAMIC_CLASS(AddTagFrame);

public:

    void OnItemRigthClicked(wxCommandEvent& event);
    void OnPopupClick(wxCommandEvent& event);

...
}


AddTagFrame.cpp
void AddTagFrame::OnItemRigthClicked( wxCommandEvent& event )
{
// тут this имеет один адрес
    wxMenu popup_menu;
// тут this имеет другой адрес
    popup_menu.Append(ID_AddTag, "Добавить тег");
// тут this имеет третий адрес
    popup_menu.Connect(wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&AddTagFrame::OnPopupClick, NULL, this);
// тут this имеет четвёртый адрес
    PopupMenu(&popup_menu);
// тут this имеет пятый адрес
}
// почему? разве так должно быть?

void AddTagFrame::OnPopupClick( wxCommandEvent& event )
{
// m_clientThread это weak_ptr и до вызова lock() имеет корректное значение
    if (boost::shared_ptr<OPCClientThread> sp_client = m_clientThread.lock())
    {
// sp_client = 0
// m_clientThread.px = ???
// а дальше имеет проблемы, с которых я начал.
        long itemIndex = -1;

        for (;;)
        {
            itemIndex = tagList->GetNextItem(itemIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
            if (itemIndex == -1)
            {
                break;
            }

            sp_client->AddTag( tagList->GetItemText(itemIndex) );

        }
    }
}

Почему lock() может отрабатывать таким образом?

weak_prt<OPCClientThread> m_clientThread;
// где
class OPCClientThread : public wxEvtHandler, public wxThread, public boost::enable_shared_from_this<OPCClientThread>, boost::noncopyable
{
...
}


Ещё один немаловажный фактор:
Если я подключаюсь к локальному com объекту, то всё работает нормально. Проблемы возникают, если я подключаюсь к удалённому com объекту.
Различие только в одном классе:

class COPCHost  
{
public:
    COPCHost();
    virtual ~COPCHost();
    virtual void getListOfDAServers(CATID cid, CAtlArray<CString> &listOfProgIDs) = 0;
    virtual COPCServer * connectDAServer(const CString & serverProgID) = 0;
};

class CRemoteHost : public COPCHost
{
private:

    CString host;

    void makeRemoteObject(const IID requestedClass, const IID requestedInterface, void** interfacePtr);

    CLSID GetCLSIDFromRemoteRegistry(const CString & hostName, const CString &progID);

public:
    CRemoteHost(const CString & hostName);

    void getListOfDAServers(CATID cid, CAtlArray<CString> &listOfProgIDs);

    COPCServer* connectDAServer(const CString & serverProgID);

    COPCServer* connectDAServer(const CLSID & serverClassID);
};

class CLocalHost : public COPCHost
{
public:
    CLocalHost();

    void getListOfDAServers(CATID cid, CAtlArray<CString> &listOfProgIDs);

    COPCServer * connectDAServer(const CString & serverProgID);
};

Но вроде ничего криминального тут не вижу...
Re[4]: исчезают интерфейсы
От: nen777w  
Дата: 24.12.10 17:27
Оценка:
спешу, бегло посмотрел код.
передаешь COM интерфейс в другой поток? его сериализовать надо перед этим. API точно не помню что то вроде CoComSerializeInterface()
Re[4]: исчезают интерфейсы
От: Centaur Россия  
Дата: 26.12.10 06:31
Оценка: 2 (1)
Здравствуйте, 13akaEagle, Вы писали:

E>void AddTagFrame::OnItemRigthClicked( wxCommandEvent& event )
E>{
E>// тут this имеет один адрес
E>    wxMenu popup_menu;
E>// тут this имеет другой адрес
E>    popup_menu.Append(ID_AddTag, "Добавить тег");
E>// тут this имеет третий адрес
E>    popup_menu.Connect(wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&AddTagFrame::OnPopupClick, NULL, this);
E>// тут this имеет четвёртый адрес
E>    PopupMenu(&popup_menu);
E>// тут this имеет пятый адрес
E>}
E>// почему? разве так должно быть?

Так не должно и не может быть. Но такие вопросы обычно задают люди, попытавшиеся следить за значениями локальных переменных и аргументов в дебаггере, особенно в релизной сборке с оптимизациями.

Встроенный дебаггер Visual Studio не знает про оптимизации и не даёт осмысленных результатов в их присутствии.
Re[5]: исчезают интерфейсы
От: s_viy  
Дата: 03.01.11 08:04
Оценка:
Здравствуйте, nen777w, Вы писали:

N>спешу, бегло посмотрел код.

N>передаешь COM интерфейс в другой поток? его сериализовать надо перед этим. API точно не помню что то вроде CoComSerializeInterface()
Это маршалинг называется и используется при передаче в другой апартамент с помощью функций с лаконичными названиями:
CoMarshalInterThreadInterfaceInStream
CoGetInterfaceAndReleaseStream
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.