информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяСетевые кракеры и правда о деле ЛевинаАтака на Internet
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Блокировка российских аккаунтов... 
 Отзыв сертификатов ЦБ РФ, ПСБ,... 
 Памятка мирным людям во время информационной... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[C++] ATL & .NET 2003 12.10.05 08:16  Число просмотров: 1809
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Наткнулся на вопрос в .NET 2003 о создании дополнительных интерфейсов. Наверное, я тупой...

Упростим задачу. Пусть есть COM ATLSomeObject объект, который имеет единственный интефейс IATLSomeObject, имеющий единственный метод Message( void ). Надо добавить второй интерфейс IATLSomeObject2, имеющий одноимённый метод Message(void).

Читаем MSDN. Там две возможности. Выбираем вторую, визардовую ...и ... упс визард не хочет ничего добавлять несмотря на то, что макро BEGIN_COM_MAP я уже добавил ( MS говорит, что без этого не будет работать... а оно хоть с этим, хоть без этого не печатает...). Это вопрос # 1. Почему визард не помогает приладить новый (дополнительный) интерфейс.

Тогда, перехожу к первому способу. Руками добавляю в idl второй интерфейс IATLSomeObject2 с методом Message. Пробую в меню "Implement interface". Работает. Что интересно, совершенно безразлично определил я ранее BEGIN_COM_MAP, или не определил. Это вопрос # 2. Непонятность это потому, что как сказано в MSDN, без BEGIN_COM_MAP вроде как вообще и не добавить дополнительный интерфейс. А добавляется ведь...

Ладно, думаю, хоть сервер и собирается без ошибок и предупреждений, но клиент уж точно не будет работать, поскольку, я заветный макро BEGIN_COM_MAP закоментировал, а без него, вроде как и не будет QueryInterface. Наивный... Оно работает.
Это вопрос # 3. и самая большая непонятность. Как компилятор .NET 2003, работая с ATL проектом, умеет сообразить только на основании наследования интерфейса (чисто C++ наследование, см. ниже;c таким же успехом можно было бы отнаследоваться от чего угодно, не связанного с COM), что надо построить соответствующую правильную DllGetClassObject, если мы не определяли в классе COM_INTERFACE_ENTRY.

Для простоты, привожу очень простой код сервера и клиента. Без всяких проверок. Клиент намерено сделан без smart poiners, чтобы за спиной ничего не стояло. Сервер в одном .h файлев основном.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Server
//

#pragma once
#include "resource.h"


//
// IATLSomeObject interface
//
[
object,
uuid("456EDE06-67D6-4B2B-8A1A-D502850479EA"),
dual, helpstring("Interface # 1"),
pointer_default(unique)
]
__interface IATLSomeObject : IDispatch
{
[id(1), helpstring("method Message")] HRESULT Message(void);
};



//
// IATLSomeObject2 interface
//
[
object,
uuid("8F08C8B6-A53E-4d89-8265-988623204FBA"),
dual, helpstring("Interface # 2"),
pointer_default(unique)
]
__interface IATLSomeObject2 : IDispatch
{
[id(1), helpstring("method Message")] HRESULT Message(void);
};



//
// CATLSomeObject
//
[
coclass,
threading("apartment"),
vi_progid("atl_test.ATLSomeObject"),
progid("atl_test.ATLSomeObject.1"),
version(1.0),
uuid("AE3049F3-006D-40A3-8B68-045CF91DD213"),
helpstring("ATLSomeObject Class")
]
class ATL_NO_VTABLE CATLSomeObject :
public IATLSomeObject,
public IATLSomeObject2
{
public:
CATLSomeObject()
{
}


DECLARE_PROTECT_FINAL_CONSTRUCT()
/*
BEGIN_COM_MAP(CATLSomeObject)
COM_INTERFACE_ENTRY(IATLSomeObject)
COM_INTERFACE_ENTRY(IATLSomeObject2)
END_COM_MAP()
*/
HRESULT FinalConstruct()
{
return S_OK;
}

void FinalRelease()
{
}

//
// Interface
//

// IATLSomeObject Methods
public:
STDMETHOD(IATLSomeObject::Message)(void)
{
MessageBox(0, "Interface # 1 Message(void)", "ATLSomeObject", 0);
return S_OK;
}


// IATLSomeObject2 Methods
public:
STDMETHOD(IATLSomeObject2::Message)(void)
{
MessageBox(0, "Interface # 2 Message(void)", "ATLSomeObject", 0);
return S_OK;
}
};


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Client
//



#include "stdafx.h"
#include <windows.h>
#include <initguid.h>


DEFINE_GUID(CLSID_Object,
0xAE3049F3, 0x006D, 0x40A3, 0x8b, 0x68, 0x4, 0x5c, 0xf9, 0x1d, 0xd2, 0x13);

//
// first interface
//
DEFINE_GUID(IID_Interface1,
0x456EDE06, 0x67D6, 0x4B2B, 0x8a, 0x1a, 0xd5, 0x2, 0x85, 0x4, 0x79, 0xea);
interface Interface1 : public IDispatch
{
STDMETHOD( InterfaceMessage ) () PURE;
};


//
// second interface
//
DEFINE_GUID(IID_Interface2,
0x8F08C8B6, 0xA53E, 0x4d89, 0x82, 0x65, 0x98, 0x86, 0x23, 0x20, 0x4f, 0xba);
interface Interface2 : public IDispatch
{
STDMETHOD( InterfaceMessage ) () PURE;
};



void main()
{
::CoInitialize( NULL );

Interface1* pInterface1 = NULL;
Interface2* pInterface2 = NULL;

::CoCreateInstance( CLSID_Object, NULL, CLSCTX_INPROC, IID_Interface1,(void **) &pInterface1);

pInterface1->InterfaceMessage();
pInterface1->QueryInterface( IID_Interface2, (void **) &pInterface2);
pInterface2->InterfaceMessage();

pInterface1->Release();
pInterface2->Release();

::CoUninitialize();
}


Спасибо, если кто-то прояснит мне эти нюансы ( скорее пробелы в моём образовании ;) ).
<programming> Поиск 






Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2022 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach