Несколько вопросов про COM и ATL
От: Libra Россия  
Дата: 07.12.04 10:51
Оценка:
Всем доброго времени суток.
У меня скорее теоретический вопрос, чем практический.
Допустим есть некий COM-компонент реализованный на ATL (если что не так с терминологией поправте плз). Назовём его File. Для него необходимо зоздать несколько методов и свойств. Например
Вопросы:
1) Возможно ли свойство OpenMode сделать перечисляемым типом, что бы можно было использовать константы omRead или omWrite на стороне клиента?
Напрмер написать следующий код в клиентском приложении (код абстрактный)
  file.OpenMode = omReader
  //....
  if(file.OpenMode == omWrite)
  {
    //...
  }

2) Поскольку любой метод COM-ов должен возвращать HRESULT (по крайней мере визард VS 2003 не позволяет вернуть что-либо другое) вопрос такой. Как сделать возможным написание следующего куска кода
   if(file.IsOpen())
   {
     //...
   }

или
  LONG res = file.Open("file.txt"); //где res - код ошибки


За примеры буду очень благодарен.
Спасибо всем откликнувшимся.
Удачи.
Species come and go, but the earth stands forever fast...
Re: Несколько вопросов про COM и ATL
От: Tom Россия http://www.RSDN.ru
Дата: 07.12.04 11:15
Оценка: 2 (1)
> 1) Возможно ли свойство OpenMode сделать перечисляемым типом, что бы можно было использовать константы omRead или omWrite на стороне клиента?
> Напрмер написать следующий код в клиентском приложении (код абстрактный)
>
>   file.OpenMode = omReader
>   //....
>   if(file.OpenMode == omWrite)
>   {
>     //...
>   }
>

Возможно. Для этого в IDL-е надо описать enum и сделать свойство данного типа:
 [
  public,
  uuid(1FA530DE-3020-42f2-AF01-49E76AC7C273)
 ]
 typedef enum OpenModeTag
 {
  omWrite,
  omRead
 } OpenMode;


> 2) Поскольку любой метод COM-ов должен возвращать HRESULT (по крайней мере визард VS 2003 не позволяет вернуть что-либо другое) вопрос такой. Как сделать возможным написание следующего куска кода

>
>    if(file.IsOpen())
>    {
>      //...
>    }
>

> или
>
>   LONG res = file.Open("file.txt"); //где res - код ошибки
>

>
> За примеры буду очень благодарен.
> Спасибо всем откликнувшимся.
> Удачи.

Возможно. В реализации метода IsOpen есть 2 подхода. 1 сделат ьсигнатуру метода такой:

HRESULT IsOpen([out, retval] VARIANT_BOOL* pVal);


И возвращать значение соответственно через pVal. Этот способ самый правильный с точки зрения COM. Но есть и другой. Сделать сигнатуру метода такой:

HRESULT IsOpen();


В данном случае надо возвращать ошибочный HRESULT в случае, если файл не открыт. Это более удобно, для C++ клиентов, но менее удобно для скриптов, так как в данном случае ошибочный HRESULT будет исталковын скриптом как исключение, которое надо будет перехватывать. Что касается file.Open(...), либо через out параметр, что более "кошерно", либо через HRESULT, что более удобно для C++. Ещё замечу, что в твоём случае будет удобен макрос HRESULT_FROM_WIN32, для конвертирования win32 ошибок в COM-овские
Posted via RSDN NNTP Server 1.9 delta
Народная мудрось
всем все никому ничего(с).
Re: Несколько вопросов про COM и ATL
От: white_znake  
Дата: 07.12.04 11:18
Оценка: 1 (1)
Здравствуйте, Libra, Вы писали:

L>Всем доброго времени суток.

L>У меня скорее теоретический вопрос, чем практический.
L>Допустим есть некий COM-компонент реализованный на ATL (если что не так с терминологией поправте плз). Назовём его File. Для него необходимо зоздать несколько методов и свойств. Например
L> L>Вопросы:
L>1) Возможно ли свойство OpenMode сделать перечисляемым типом, что бы можно было использовать константы omRead или omWrite на стороне клиента?
L>Напрмер написать следующий код в клиентском приложении (код абстрактный)
L>
L>  file.OpenMode = omReader
L>  //....
L>  if(file.OpenMode == omWrite)
L>  {
L>    //...
L>  }
L>

L>2) Поскольку любой метод COM-ов должен возвращать HRESULT (по крайней мере визард VS 2003 не позволяет вернуть что-либо другое) вопрос такой. Как сделать возможным написание следующего куска кода
L>
L>   if(file.IsOpen())
L>   {
L>     //...
L>   }
L>

L>или
L>
L>  LONG res = file.Open("file.txt"); //где res - код ошибки
L>


L>За примеры буду очень благодарен.

L>Спасибо всем откликнувшимся.
L>Удачи.

предположим что у тебя есть следующая функция в IFile:

HRESULT Open(/*[in]/* BSTR bstrFileName, /*[out]/* LONG * pRetValue);

затем в оболочке для IFile у тебя есть метод:

LONG Open(BSTR bstrFileName)
{
LONG lResult;
IFile->Open(bstrFileName, &lResult);
return lResult;
}
Re[2]: Несколько вопросов про COM и ATL
От: Аноним  
Дата: 07.12.04 11:21
Оценка:
Tom>
Tom>HRESULT IsOpen();
Tom>


Tom>В данном случае надо возвращать ошибочный HRESULT в случае, если файл не открыт. Это более удобно, для C++ клиентов, но менее удобно для скриптов, так как в данном случае ошибочный HRESULT будет исталковын скриптом как исключение, которое надо будет перехватывать.


Можно еще возвращать не ошибочный, а успешный HRESULT, отличный от S_OK, например, S_FALSE. Хотя как этому отнесутся скрипты — не знаю.
Re: Несколько вопросов про COM и ATL
От: nii_im_b Мухосранск  
Дата: 07.12.04 11:28
Оценка: 1 (1)
Здравствуйте, Libra, Вы писали:


L>Вопросы:

L>1) Возможно ли свойство OpenMode сделать перечисляемым типом, что бы можно было использовать константы omRead или omWrite на стороне клиента?
L>Напрмер написать следующий код в клиентском приложении (код абстрактный)
L>
L>  file.OpenMode = omReader
L>  //....
L>  if(file.OpenMode == omWrite)
L>  {
L>    //...
L>  }
L>


да... возможно. для этого enum надо прописать в идл файле.

import "oaidl.idl";
import "ocidl.idl";
[
  uuid(00000000-0000-0000-0000-000000000000),
  version(1.0),
  helpstring("smth_lib_ 1.0 Type Library")
] library smth_lib_Lib
{

  importlib("stdole2.tlb");

   typedef enum _tag_smth_type
   {
      type_1 = 0x01,
      type_2 = 0x02
   }smth_type;
.......................
}




L>2) Поскольку любой метод COM-ов должен возвращать HRESULT (по крайней мере визард VS 2003 не позволяет вернуть что-либо другое) вопрос такой. Как сделать возможным написание следующего куска кода

L>
L>   if(file.IsOpen())
L>   {
L>     //...
L>   }
L>

L>или
L>
L>  LONG res = file.Open("file.txt"); //где res - код ошибки
L>


возвращать можно не только HRESULT достаточно вспомнить IUnknown::Addref && Release
они возвращают ULONG.

а вообще присуцтвуют [in][out/retval] параметры.
Re[2]: Несколько вопросов про COM и ATL
От: Libra Россия  
Дата: 07.12.04 11:50
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Возможно. Для этого в IDL-е надо описать enum и сделать свойство данного типа:

Tom>
Tom> [
Tom>  public,
Tom>  uuid(1FA530DE-3020-42f2-AF01-49E76AC7C273)
Tom> ]
Tom> typedef enum OpenModeTag
Tom> {
Tom>  omWrite,
Tom>  omRead
Tom> } OpenMode;

Tom>


а если это put/get свойство, то вот это правильно?
 [
  public,
  uuid(1FA530DE-3020-42f2-AF01-49E76AC7C273)
 ]

interface IFile : IDispatch
{

 typedef enum OpenModeTag
 {
  omWrite,
  omRead
 } OpenModeType;
 [propget, id(1), helpstring("...")] HRESULT OpenMode([out,retval]OpenModeType *pVal);
 [propput, id(1), helpstring("...")] HRESULT OpenMode([in]OpenModeType newVal);

};
Species come and go, but the earth stands forever fast...
Re[3]: Несколько вопросов про COM и ATL
От: Tom Россия http://www.RSDN.ru
Дата: 07.12.04 11:52
Оценка:
> а если это put/get свойство, то вот это правильно?
Правильно
Posted via RSDN NNTP Server 1.9 delta
Народная мудрось
всем все никому ничего(с).
Re: Несколько вопросов про COM и ATL
От: Libra Россия  
Дата: 07.12.04 13:39
Оценка:
Спасибо за помощь. Со свойствами и методами разобрался с вашей помощью.
Назрела еще пара вопросов.
1) Что за флаг Attributed, который можно выставить при создания ATL проекта?
2) Законно ли в COM объектах использовать стандартные функции WIN API для создания и управления потоками (такие как CreateThread, TerminateThread и пр.)?

З.Ы.
мой COM-сервер это DLL, флаг Attributed снят.
Species come and go, but the earth stands forever fast...
Re[2]: Несколько вопросов про COM и ATL
От: nii_im_b Мухосранск  
Дата: 07.12.04 14:03
Оценка:
Здравствуйте, Libra, Вы писали:

L>Спасибо за помощь. Со свойствами и методами разобрался с вашей помощью.

L>Назрела еще пара вопросов.
L>1) Что за флаг Attributed, который можно выставить при создания ATL проекта?

грубо говоря этот флаг выставляется для того, чтоб меньше лазили в идл коде. особой смысловой нагрузки я не вижу. для примера в ВС6 его просто нет.


L>2) Законно ли в COM объектах использовать стандартные функции WIN API для создания и управления потоками (такие как CreateThread, TerminateThread и пр.)?


запросто. в ком можно использовать даже МФС (если включить мфс суппорт)

L>З.Ы.

L>мой COM-сервер это DLL, флаг Attributed снят.
Re[2]: Несколько вопросов про COM и ATL
От: Tom Россия http://www.RSDN.ru
Дата: 07.12.04 14:27
Оценка:
"Libra" <6805@users.rsdn.ru> wrote in message news:935741@news.rsdn.ru...
> Спасибо за помощь. Со свойствами и методами разобрался с вашей помощью.
> Назрела еще пара вопросов.
> 1) Что за флаг Attributed, который можно выставить при создания ATL проекта?
Попытка (провальная) Microsoft-а применить атрибуты для unmanaged (читай не .NET) кода. Использовать НЕ советую. Кстате использовать атрибуты можно и не устанавливая эту птичку. Это можно делать даже для простого консольного проекта.

> 2) Законно ли в COM объектах использовать стандартные функции WIN API для создания и управления потоками (такие как CreateThread, TerminateThread и пр.)?

Законно. Надо только не забыть вызвать CoInitialize[Ex] в потоке. Так же лучше пользоваться __beginthreadex, для инициализации С++ рантайма.
Posted via RSDN NNTP Server 1.9 delta
Народная мудрось
всем все никому ничего(с).
Re[3]: Несколько вопросов про COM и ATL
От: Libra Россия  
Дата: 07.12.04 15:01
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Законно. Надо только не забыть вызвать CoInitialize[Ex] в потоке. Так же лучше пользоваться __beginthreadex, для инициализации С++ рантайма.


На сколько я понял из MSDN, вызов функции CoInitialize(NULL) в функции фторичного потока необходим только в том случае если в ней будет использовано что-либо COM-овское.
А если я пишу напрмер вот такой код, нужно ли производит вышеобозначенный вызов?

void thread_func(void *arg)
{
   CMyATLCtrl *owner = reinterpret_cast<CMyATLCtrl*>(arg);
   //...
   owner_->Fire_OnMouseDown(x, y);
   //...
}
//...
void CMyATLCtrl::StartThread()
{
   thread_hndl_ = CreateThread(..., &thread_func, this, ...); //не помню сигнатуры...
}
Species come and go, but the earth stands forever fast...
Connection Points и многопоточность
От: Tom Россия http://www.RSDN.ru
Дата: 07.12.04 15:06
Оценка: 23 (2)
#Имя: FAQ.com.cp.multithreaded
> 2) Законно ли в COM объектах использовать стандартные функции WIN API для создания и управления потоками (такие как CreateThread, TerminateThread и пр.)?

Законно. Надо только не забыть вызвать CoInitialize[Ex] в потоке. Так же лучше пользоваться __beginthreadex, для инициализации С++ рантайма.

> А если я пишу напрмер вот такой код, нужно ли производит вышеобозначенный вызов?


void thread_func(void *arg)
{
   CMyATLCtrl *owner = reinterpret_cast<CMyATLCtrl*>(arg);
   //...
   owner_->Fire_OnMouseDown(x, y);
   //...
}

//...
void CMyATLCtrl::StartThread()
{
   thread_hndl_ = CreateThread(..., &thread_func, this, ...); //не помню сигнатуры...
}

Нужен. И не только инициализация COM-а. Ещё нужна замена стандартной реализации Connection Point-ов на ту (IConnectionPointImplMT), которая поддерживает многопоточность. См. http://support.microsoft.com/kb/q280512/ (см. также http://rsdn.ru/Forum/Message.aspx?mid=905310&amp;only=1
Автор: shrek
Дата: 18.11.04
)
Posted via RSDN NNTP Server 1.9 delta
Народная мудрось
всем все никому ничего(с).
Re[5]: Несколько вопросов про COM и ATL
От: Libra Россия  
Дата: 07.12.04 15:47
Оценка:
Здравствуйте, Tom, Вы писали:
Огромное спасибо.
Вы мне очень помогли.
Species come and go, but the earth stands forever fast...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.