информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Страшный баг в WindowsАтака на InternetГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[C++] ATL & .NET 2003 12.10.05 08:16  
Автор: 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();
}


Спасибо, если кто-то прояснит мне эти нюансы ( скорее пробелы в моём образовании ;) ).
Разобрался. 12.10.05 22:36  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Разобрался.
Попробовал проект без атрибутов класса - ясно стало ;)) . Единственное несответствие, которое нашёл, что пока ручками в idl не пропишешь новый интерфейс - всё равно не работает визард "implement interface", а должен бы, как написано в MSDN.

Ещё вопрос. Attributed класс - очень уж удобное дело. Какое преимущество в использовании проекта с классами без атрибутов?

Спасибо всем.
Не разобрался... 13.10.05 07:40  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Не разобрался...
(типа сам с собой :))))

Наверное, я всёже не то, что-то делаю, или не понимаю, или это действительно баг у MS
Оба типа COM ( 1) проект ATL attributed; 2) проект ATL с объектами без атрибутов ) прекрасно работают с C++ клиентами, т.е. в обоих случаях оба интерфейса прекрасно разрешаются, так что вызываются методы в коде типа:

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();


Но вот в клиенте C# как оказывается запросить оба интерфейса можно только для COM, который сделан с ATL attributed классами.
Т.е. можно повторить С++ вызовы в C# для обоих интерфейсов в коде типа


CATLSomeObjectClass coATL_AttributeCls = new CATLSomeObjectClass();
IATLSomeObject InterfaceAttributed1 = ( IATLSomeObject ) coATL_AttributeCls;
IATLSomeObject2 InterfaceAttributed2 = ( IATLSomeObject2 ) coATL_AttributeCls;

InterfaceAttributed1.Message();
InterfaceAttributed2.Message();


Если же объекты сделаны без атрибутов, то ничего подобного не удаётся сделать в клиенте C# (в отличии от C++). В этом случае второго интерфейса не видно напрочь. Такое ощущение, что всё же в этом моём проекте без аттрибутов где-то косяки... Хоть и работает с C++ клиентами на ура.

Если кто сталкивался подскажите, плз.
Сам себя к столбу позора 14.10.05 05:37  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Не удаляю ветку, чтоб другим не повадно было так же ....
Так сказать сам себя к столбу позора.
Парни, мне очень стыдно... Я просто в idl описании класса забыл второй интерфейс вставить.
1




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


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