ВОПРОС
От: alexei_  
Дата: 23.10.01 14:00
Оценка:
Объясните мне, пожалуйста,
Как сделать СОМ — объект, такой чтоб он существовал в единственном
экземпляре, т.е. что бы CoCreateInstance возвращала указатель на один и тот же
объект (при вызове из разных процессов)
Желательно без использования MFC или ATL

Алексей
Re: ВОПРОС
От: MORBiD Россия  
Дата: 24.10.01 06:36
Оценка:
Здравствуйте alexei_, Вы писали:

A>Объясните мне, пожалуйста,

A>Как сделать СОМ — объект, такой чтоб он существовал в единственном
A>экземпляре, т.е. что бы CoCreateInstance возвращала указатель на один и тот же
A>объект (при вызове из разных процессов)
A>Желательно без использования MFC или ATL

A>Алексей


Можно посмотреть как реализована ATL::CComClassFactorySingleton, ATL::CComObjectGlobal etc. и переписать без ATL.
Re[2]: ВОПРОС
От: Alexei_  
Дата: 24.10.01 10:54
Оценка:
Здравствуйте MORBiD, Вы писали:

MORBD>Здравствуйте alexei_, Вы писали:


A>>Объясните мне, пожалуйста,

A>>Как сделать СОМ — объект, такой чтоб он существовал в единственном
A>>экземпляре, т.е. что бы CoCreateInstance возвращала указатель на один и тот же
A>>объект (при вызове из разных процессов)
A>>Желательно без использования MFC или ATL

A>>Алексей


MORBD>Можно посмотреть как реализована ATL::CComClassFactorySingleton, ATL::CComObjectGlobal etc. и переписать без ATL.


Да, но насколько я понял ...Singleton работает только для ехе-серверов,
Или я ошибаюсь ?
Re[3]: ВОПРОС
От: SergeyAksuchenko Беларусь  
Дата: 26.10.01 13:11
Оценка:
Здравствуйте Alexei_, Вы писали:

A>Здравствуйте MORBiD, Вы писали:


MORBD>>Здравствуйте alexei_, Вы писали:


A>>>Объясните мне, пожалуйста,

A>>>Как сделать СОМ — объект, такой чтоб он существовал в единственном
A>>>экземпляре, т.е. что бы CoCreateInstance возвращала указатель на один и тот же
A>>>объект (при вызове из разных процессов)
A>>>Желательно без использования MFC или ATL

A>>>Алексей


MORBD>>Можно посмотреть как реализована ATL::CComClassFactorySingleton, ATL::CComObjectGlobal etc. и переписать без ATL.


A>Да, но насколько я понял ...Singleton работает только для ехе-серверов,

A>Или я ошибаюсь ?

У тебя DLL, значит есть экспортная функция функция GetClassObject.
Каждый раз CoCreateInstance вызывает GetClassObject в DLL, если создаеться объект из твоей DLL.
Сделай так, чтобы GetClassObject возвращала указатель на единажды созданный объект. и сё.
Re[4]: ВОПРОС
От: SergeyAksuchenko Беларусь  
Дата: 26.10.01 13:13
Оценка:
Поправка: DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
Re[5]: ВОПРОС
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.10.01 18:16
Оценка:
Здравствуйте SergeyAksuchenko, Вы писали:

SA>Поправка: DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)


Это ошибка!


Взгляни на ее название — DllGetClassObject

Ничего не настораживает? Например, слово "Class"?

Эта функция возвращает объект класса который априори синглетон, но (!) это не то о чем ты думаешь.

Объектами класса никто не пользуется напрямую! Обычно COM-сервер размещенный в DLL через DllGetClassObject возвращает указатель на единственный объект — Фабрику Классов. Этот объект реализует стандартный интерфейс IClassFactory. Именно его исползоует CoCreateInstace[Ex] для создания экземпляра COM-объекта. Так что нужно изменять не DllGetClassObject, а реализацию объекта — Фабрики Классов. Если она написана руками, то вместо создания каждый раз нового объекта нужно просто возвращать указатель на единый экземпляр.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: ВОПРОС
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 26.10.01 21:01
Оценка:
Здравствуйте alexei_, Вы писали:

Все выше написаное правильно, но только если объекты создаются из одного процесса.
При вызове из РАЗНЫХ процессов будут создаваться РАЗНЫЕ копии dll, поэтому надо проверять нет ли предыдущей копии dll в памяти. Это удобно делать через расшаренную память, и в ней же тогда хранить счетчик ссылок на объект.
Re[2]: ВОПРОС
От: alexei_  
Дата: 28.10.01 09:23
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>Здравствуйте alexei_, Вы писали:


DG>Все выше написаное правильно, но только если объекты создаются из одного процесса.

DG>При вызове из РАЗНЫХ процессов будут создаваться РАЗНЫЕ копии dll, поэтому надо проверять нет ли предыдущей копии dll в памяти. Это удобно делать через расшаренную память, и в ней же тогда хранить счетчик ссылок на объект.

Во первых,Спасибо за ответы

Во -вторых, Это-то я и сам понимаю, что нужно просто возвращать из IClassFactory::CreateInstance(...) указатель на
один и тот же объект. только вот КАК ЭТО СДЕЛАТЬ, то есть в пределах одного процесса все понятно, а вот если ПРОЦЕССЫ РАЗНЫЕ ???
Re[3]: ВОПРОС
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 28.10.01 13:37
Оценка:
Здравствуйте alexei_, Вы писали:


A>Во -вторых, Это-то я и сам понимаю, что нужно просто возвращать из IClassFactory::CreateInstance(...) указатель на

A>один и тот же объект. только вот КАК ЭТО СДЕЛАТЬ, то есть в пределах одного процесса все понятно, а вот если ПРОЦЕССЫ РАЗНЫЕ ???


Примерно так, только добавить синхронизацию и удаление FileMapping'а.
Также лучше перенести создание FileMapping'а в FinalConstruct объекта, а удаление в FinalRelease.
А проверку на уже созданный объект перенести в ClassFactory.
По желанию добавить проверку ошибок.

struct S1
{
IStream * istr;
};

CComPtr<IUnknown> GetSingletonObject ()
{
HANDLE hmem = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
sizeof(S1),
"MyUniqueName");

bool is_first = GetLastError() != ERROR_ALREADY_EXISTS;

S1 * s1 = (S1*)MapViewOfFile(
hMapObject,
FILE_MAP_WRITE,
0,
0,
0);

CComPtr<IUnknown> iunk;
if (is_first)
{
// ========= !! Это не правильно !! =================
// Надо создавать объект напрямую. Посмотри реализацию Class Factory
iunk.CoCreateInstance (L"MyObject.ProgID");
//===================================================
CoMarshalInterThreadInterfaceInStream (IID_IUnknown, iunk, &s1->istr);
}
else
{
CoUnmarshalInterface (s1->istr, IID_IUnknown, (void**)&iunk.p);
}
return iunk;
}
Re[2]: ВОПРОС
От: Serge Чехия  
Дата: 29.10.01 08:09
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>Здравствуйте alexei_, Вы писали:


DG>Все выше написаное правильно, но только если объекты создаются из одного процесса.

DG>При вызове из РАЗНЫХ процессов будут создаваться РАЗНЫЕ копии dll, поэтому надо проверять нет ли предыдущей копии dll в памяти. Это удобно делать через расшаренную память, и в ней же тогда хранить счетчик ссылок на объект.

А кстати, если эту dll-ку поместить в MTS, будут ли все клиенты работать с 1 экземпляром, или каждый со своим ?
Re[3]: ВОПРОС
От: George_Seryakov Россия  
Дата: 29.10.01 16:06
Оценка:
Здравствуйте Serge, Вы писали:


S>А кстати, если эту dll-ку поместить в MTS, будут ли все клиенты работать с 1 экземпляром, или каждый со своим ?


Скорее всего — не получится, поскольку у MTS-а своя собственная фабрика классов, и вмешательства в ее работу он не любит.
GS
Re: ВОПРОС
От: Edward Россия  
Дата: 12.02.02 09:09
Оценка:
Здравствуйте alexei_, Вы писали:

A>Объясните мне, пожалуйста,

A>Как сделать СОМ — объект, такой чтоб он существовал в единственном
A>экземпляре, т.е. что бы CoCreateInstance возвращала указатель на один и тот же
A>объект (при вызове из разных процессов)
A>Желательно без использования MFC или ATL

A>Алексей


во флэйма-то

смотри функции
GetActiveObject
RegisterActiveObject
RevokeActiveObject

а так же вот этот код, он на ATL но суть, я думаю, будет ясна

template< CLSID *pclsid >
class CComClassFactoryGlobal : public CComClassFactory
{
public:
  STDMETHOD( CreateInstance )( LPUNKNOWN pUnkOuter, REFIID riid, void **ppvObj )
  {
    CComPtr< IUnknown > spUnk;
    ::GetActiveObject( *pclsid, NULL, &spUnk );

    if( NULL != spUnk.p )
      return spUnk.p->QueryInterface( riid, ppvObj );
    else
    {
      HRESULT hr = CComClassFactory::CreateInstance( pUnkOuter, riid, ppvObj );
      if( SUCCEEDED( hr ) )
      {
        CComQIPtr< IUnknown, &IID_IUnknown > spUnkCreated( ( IUnknown * )*ppvObj );
        DWORD dwRegister;
        ::RegisterActiveObject( spUnkCreated, *pclsid, ACTIVEOBJECT_WEAK, &dwRegister );
      }
      return hr;
    }
    return S_OK;
  }//CreateInstance
};
Re[4]: ВОПРОС
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.02.02 22:02
Оценка:
Здравствуйте George_Seryakov, Вы писали:

GS>Здравствуйте Serge, Вы писали:



S>>А кстати, если эту dll-ку поместить в MTS, будут ли все клиенты работать с 1 экземпляром, или каждый со своим ?


GS> Скорее всего — не получится, поскольку у MTS-а своя собственная фабрика классов, и вмешательства в ее работу он не любит.


Ерунда (и про то что работать не будет, и про фабрику классов). Если объект синглетон, то будет. Даже лучше чем обычный exe.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: ВОПРОС
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.02.02 22:03
Оценка:
Здравствуйте Edward, Вы писали:

E>во флэйма-то


А что (по-твоему) значит "флэйма"?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: ВОПРОС
От: IT Россия linq2db.com
Дата: 15.02.02 03:21
Оценка:
Здравствуйте VladD2, Вы писали:

GS>> Скорее всего — не получится, поскольку у MTS-а своя собственная фабрика классов, и вмешательства в ее работу он не любит.


VD>Ерунда (и про то что работать не будет, и про фабрику классов). Если объект синглетон, то будет. Даже лучше чем обычный exe.


Но статистику COM+ будет показывать такую, как будто он насоздавал кучу объектов , поэтому легко обмануться.

Кстати, как можно создать противоположного типа объект, чтобы на каждый экземпляр создавалась новая COM+ Application?
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: ВОПРОС
От: Edward Россия  
Дата: 15.02.02 08:52
Оценка:
Здравствуйте VladD2, Вы писали:

VD>Здравствуйте Edward, Вы писали:


E>>во флэйма-то


VD>А что (по-твоему) значит "флэйма"?

А это значит, что человек задал вопрос
"Как сделать СОМ — объект, такой чтоб он существовал в единственном экземпляре, т.е. что бы CoCreateInstance возвращала указатель на один и тот же объект (при вызове из разных процессов)",
причем вопрос был общий, то есть не уточнялось в Local или Inproc сервере живет объект.
Тут же был дан нормальный ответ с указанием на ATL::CComClassFactorySingleton, ATL::CComObjectGlobal, то есть для обоих случаев.
А потом народ начал в этой нити обсуждать какие-то свои проблемы про GetClassObject и копии Dll в памяти, не имеющие никакого отношения к вопросу, при этом жарко споря.
По моему это и называется флейм — спор ни о чем.
Или я ошибаюсь?
Re: ВОПРОС
От: ovanes  
Дата: 21.12.02 14:45
Оценка:
Здравствуйте, alexei_, Вы писали:

A>Объясните мне, пожалуйста,

A>Как сделать СОМ — объект, такой чтоб он существовал в единственном
A>экземпляре, т.е. что бы CoCreateInstance возвращала указатель на один и тот же
A>объект (при вызове из разных процессов)
A>Желательно без использования MFC или ATL

A>Алексей


Sorry, ne mogu sejchas kirillicej pisat'.

Otvet na etot vopros ochen' prost. Ne ponimaju pochemu tut stol'ko vsego mudrogo nasovetovali.
Nado sozdat' Out-Of-Process COM Server.


Vot paru statej na etu temu:


http://codeguru.earthweb.com/activex/COMApartments1.html
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/comext_6h7y.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/comext_3ib7.asp


Nadejus' chto kak-to pomozhet.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.