Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Проблема с событиями в ехе-сервере  (Прочитано 9473 раз)
0 Пользователей и 1 Гость смотрят эту тему.
FantomCat
Гость
« : 30-10-2003 16:18 » 

Здравствуйте..
У меня такая проблема. Мне необходимо подключиться к событиям СОМ-сервера (ехе-сервер). Вот код клиентского приложения
//--------------------------------
//event processing class
//--------------------------------
class CEvCon :public _ITestEvents
{
private:
    DWORD       m_dwRefCount;
public:
   CEvCon(){};
   virtual ~CEvCon(){};
   STDMETHODIMP OnMethod1(int par)
   {
       char   strTemp[10];
       sprintf(strTemp,"The result is %d", par);
      ::MessageBox(0, strTemp,"",0);
      return S_OK;;

   };


   HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
    {
        if (iid == IID__ITestEvents)
        {
            m_dwRefCount++;
            *ppvObject = (void *)this;
            return S_OK;
        }

        if (iid == IID_IUnknown)
        {
            m_dwRefCount++;            
            *ppvObject = (void *)this;
            return S_OK;
        }

        return E_NOINTERFACE;
    }
   ULONG STDMETHODCALLTYPE AddRef()
    {
        m_dwRefCount++;
        return m_dwRefCount;
    }
   
   ULONG STDMETHODCALLTYPE Release()
    {
        ULONG l;
       
        l  = m_dwRefCount--;

        if ( 0 == m_dwRefCount)
        {
            delete this;
        }
       
        return l;
    }

};
//--------------------------------
//main program
//--------------------------------

int main(int argc, char* argv[])
{
   HRESULT hres = ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
   if(!(SUCCEEDED(hres)))
   {
      return -1;
   }
   CComPtr<ITest> pTest;
   HRESULT hr =pTest.CoCreateInstance(CLSID_Test);
   if(hr != S_OK)
   {
      ::CoUninitialize();
      return -1;
   }
   IConnectionPointContainer   * pCPC;
   IConnectionPoint          * pCP;   //these are declared as a member
    DWORD                    dwAdvise; //variable,shown here for completeness
   hr = pTest->QueryInterface(IID_IConnectionPointContainer,(void **)&pCPC);

    if ( !SUCCEEDED(hr) )
    {
      ::CoUninitialize();
        return -1;
    }

    hr = pCPC->FindConnectionPoint(IID__ITestEvents,&pCP);
   
   if ( !SUCCEEDED(hr) )
    {
        ::CoUninitialize();
        return -1;
    }
   pCPC->Release();
   
   IUnknown *pSinkUnk;
   
   CEvCon *pCnn;
    pCnn = new CEvCon;

    if ( !pCnn )
    {
        ::CoUninitialize();
        return -1;
    }

    //Get the pointer to CEvCon's Unknown pointer   
   hr = pCnn->QueryInterface (IID_IUnknown,(void **)&pSinkUnk);
   hr = pCP->Advise(pSinkUnk,&dwAdvise);
   pTest->Method1(3);

   pCP->Unadvise(dwAdvise);
   ..pTest->OutMet();
   pCP->Release();


   ::CoUninitialize();
   return 0;
}

Так вот так вот клиент не хочет адвайзиться к событиям. А вот если в сервере и рабочий и событийный интерфейсы унаследованы от IUnknown. А если сделать сервак в виде dll-ки, то все адвайзится, притом что код сервера - слово в слово. А мне длл-снрвер никак не подходит, нужен ехе.
Плз, помогите, может кто сталкивался с таким.
Записан
NetRaider
Гость
« Ответ #1 : 30-10-2003 23:47 » 

Цитата
Здравствуйте.. У меня такая проблема. Мне необходимо подключиться к событиям СОМ-сервера (ехе-сервер).
 ...

Так вот так вот клиент не хочет адвайзиться к событиям. А вот если в сервере и рабочий и событийный интерфейсы унаследованы от IUnknown. А если сделать сервак в виде dll-ки, то все адвайзится, притом что код сервера - слово в слово. А мне длл-снрвер никак не подходит, нужен ехе.
Плз, помогите, может кто сталкивался с таким.

Во первых как-то странно выглядят проверки
Код:
if ( !SUCCEEDED(hr) ) 
{
::CoUninitialize();
return -1;
}

Лучше ипользовать
Код:
if(FAILED(hr))
{
    ::CoUninitialize();
    return -1;
}

Во вторых - телепаты в отпуске Улыбаюсь - В каком именно месте вылетает, и чему в этот момент равен hr. Без этих данных сложно что-либо посоветовать, причин может быть много...
« Последнее редактирование: 20-11-2007 18:17 от Алексей1153++ » Записан
Anonymous
Гость
« Ответ #2 : 31-10-2003 07:43 » 

Да уже клиентов куча наделана, в том числе и такой вариант
#include <atlbase.h>
#include <ole2.h>

CComModule _Module;

#include <atlcom.h>
#include <objbase.h>
#include "../ConPoint.h"
#import "../ConPoint.tlb" named_guids raw_interfaces_only
 

class CConEvent:
   public CComObjectRootEx<CComSingleThreadModel>,
   public _ITestEvents
{
public:
//   CConEvent(){};
   BEGIN_COM_MAP(CConEvent)
      COM_INTERFACE_ENTRY(_ITestEvents)
   END_COM_MAP()
   virtual HRESULT STDMETHODCALLTYPE OnMethod1(int par)
   {
      char   strTemp[10];
       sprintf(strTemp,"The result is %d", par);
      return S_OK;
   };
};


int main(int argc, char* argv[])
{
   if(FAILED(::CoInitializeEx(NULL,COINIT_MULTITHREADED)))
      return -1;
   ITest *pTest;
   HRESULT hr;
   try
   {
      if(FAILED(hr = ::CoCreateInstance(CLSID_Test,NULL,CLSCTX_LOCAL_SERVER,IID_ITest,(LPVOID*)&pTest)))throw -1;
      
      typedef CComObject<CConEvent> CConEventImpl;
      CConEventImpl*pConImpl = new CConEventImpl;
      CComQIPtr<_ITestEvents, &IID__ITestEvents> Cnn(pConImpl);

      DWORD dwCookie;
      if(FAILED(hr = AtlAdvise((LPUNKNOWN)pTest,(LPUNKNOWN)Cnn.p, IID__ITestEvents, &dwCookie)))throw -2;
      pTest->Method1(7);

      if(FAILED(hr = AtlUnadvise((LPUNKNOWN)pTest,IID__ITestEvents,dwCookie)))throw -3;
      pTest->Release();
      
      delete pConImpl;
   }
   catch(int er)
   {
      ::CoUninitialize();
      return er;
   }
   pTest->Release();
   return 0;
}
Так вот на AtlAdvise hr получается равным -1073741819 (0xc0000005) при любом раскладе, на любом компе и с любым клиентом..
Че делать?!! Я шокирован! Тут никто продуплить не может... И почему с таким точно длл-сервером все адвайзится?  Так больше нельзя...  Сроки горят!!!
Записан
NetRaider
Гость
« Ответ #3 : 01-11-2003 00:28 » 

Цитата
Так вот на AtlAdvise hr получается равным -1073741819 (0xc0000005) при любом раскладе, на любом компе и с любым клиентом..

Ситуация прояснилась... При AtlAdvise указатель pTest передается в другой процесс. Там он естественно не является валидным. Это можно обойти следующим способом:

Воспользоваться стандартным маршалингом. Для этого всем интерфейсам "торчащим" из exe-сервера нужно в idl присвоить аттрибут [oleautomation] и сделать rebuild. Затем в main/winmain сервера после CoInitialize добавить следующий код:

Код:
ITypeLib* pTlb;
LoadTypeLibEx(L"blablabla.tlb", REGKIND_REGISTER, &pTlb);
pTlb->Release();

"blablabla.tlb" заменить на имя своей tlb.
Вот вроде и все...
Единственный минус - приходится таскать с собой *.tlb.
« Последнее редактирование: 20-11-2007 18:18 от Алексей1153++ » Записан
FantomCat
Гость
« Ответ #4 : 01-11-2003 15:30 » new

NetRaider, огромное тебе спасибо за ответ, но я уже извратилась по другому через диспатчи так, что все теперь работает. Я тут кричала от радости, но меня все поняли, т.к. я тут из системщиков одна... А все остальные по басику да делфям прикладнуху катают..
Если вдруг у кого возникнет подобная трабла, пишите мне на redcatty@mail.ru
Кину исходничек... И вообще - MSDN FOREVER! 8)

А предложенный вариант я тоже попробую. Такие вещи надо коллекционировать. Еще раз огромное спасибо!!!
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines