Active Objects
От: Sero США  
Дата: 23.05.02 17:38
Оценка:

Когда создаеш COM объект то каждый раз создается новый екземпляр этого объекта
CoCreateInstanse()

или
ISomeObject obj;
obj.CreateDispatch("Obj.ProgID");

или
Basic
Dim obj As Object
Set obj = CreateObject("Obj.ProgID")


если хотим из двух разных процессов вызывать один и тот же объект надо зарегистрировать его как ActiveObject
а при вызове сначала проверять нет ли уже созданного , если есть просто подсоединиться к нему. Так даже можно передавать данные между процессами.

ис MSDN
GetActiveObject          Retrieves an instance of an object that is initialized with OLE.  
RegisterActiveObject     Initializes a running object with OLE. (Use when application starts.) 
RevokeActiveObject       Revokes a running application's initialization with OLE. (Use when application ends.)


Кто нибудъ может сказать верны ли вышеприведенные высказывания ?, и где можно об этом поподробнее прочитать ???
и Еще, можнон ли подсоединиться к активному объекту из VB ili VBScript ???
есть ли разница между

Dim obj As Object
и
Dim obj As Obj.ProgID ???
X
Re: Active Objects
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.05.02 02:43
Оценка: 3 (1)
Здравствуйте Sero, Вы писали:

S>

S>Когда создаеш COM объект то каждый раз создается новый екземпляр этого объекта
[skipped]
S>если хотим из двух разных процессов вызывать один и тот же объект надо зарегистрировать его как ActiveObject
S>а при вызове сначала проверять нет ли уже созданного , если есть просто подсоединиться к нему. Так даже можно передавать данные между процессами.
[skipped]
S>Кто нибудъ может сказать верны ли вышеприведенные высказывания?

Абсолютно верно.

S>и Еще, можнон ли подсоединиться к активному объекту из VB ili VBScript ???

S>есть ли разница между

S>Dim obj As Object

S>и
S>Dim obj As Obj.ProgID ?

Оба определения описывают некоторый СОМ объект. Разница лишь в требуемом от объекта интерфейсе и в последующих вызовах его метода.

Просто "Object" говорит о том, что это обыкновенный диспатч-объект (т.е. тип объект НЕ определен на этапе компиляции), и VB будет запрашивать у него интерфейс IDispatch, Все методы будут вызваны через механизм "позднего связывания", или только через одну функцию Invoke для всех методов объекта с запросом имени метода через GetIDsOfNames.

"Obj.ProgID" говорит о том, что тип объект определен на этапе компиляции, у него известен интерфейс и известны все методы этого интерфейс через Библиотеку Типов (TLB) объекта. Все методы будут вызваны наискорейшим способом, доступным для интерфейса: через виртуальную таблицу или через Invoke без запроса имени метода (по его ID).
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re: Active Objects
От: Vi2 Удмуртия http://www.adem.ru
Дата: 24.07.02 05:46
Оценка: 3 (1)
Здравствуйте Sero, Вы писали:

S>если хотим из двух разных процессов вызывать один и тот же объект надо зарегистрировать его как ActiveObject

S>а при вызове сначала проверять нет ли уже созданного , если есть просто подсоединиться к нему. Так даже можно передавать данные между процессами.

S>ис MSDN
S>GetActiveObject          Retrieves an instance of an object that is initialized with OLE.  
S>RegisterActiveObject     Initializes a running object with OLE. (Use when application starts.) 
S>RevokeActiveObject       Revokes a running application's initialization with OLE. (Use when application ends.)


S>... И еще, можно ли подсоединиться к активному объекту из VB ili VBScript?


Можно.
Dim obj As Object ' или Dim obj As ObjLib.ProgIDClass
Set obj = GetObject(,"Obj.ProgID") ' сначала уже существующий
If obj Is Nothing Then
  Set obj = CreateObject("Obj.ProgID") ' если нет, пытаемся создать новый 
End If


Реальный пример
Dim obj As Object ' или Dim obj As Word.Application
Set obj = GetObject(,"Word.Application") ' сначала уже существующий Word
If obj Is Nothing Then
  Set obj = CreateObject("Word.Application") ' если нет, пытаемся запустить новый Word
End If
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Active Objects
От: Sero США  
Дата: 25.07.02 08:10
Оценка:
Здравствуйте Vi2, Вы писали:

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


S>>если хотим из двух разных процессов вызывать один и тот же объект надо зарегистрировать его как ActiveObject

S>>а при вызове сначала проверять нет ли уже созданного , если есть просто подсоединиться к нему. Так даже можно передавать данные между процессами.

Vi2>
S>>ис MSDN
S>>GetActiveObject          Retrieves an instance of an object that is initialized with OLE.  
S>>RegisterActiveObject     Initializes a running object with OLE. (Use when application starts.) 
S>>RevokeActiveObject       Revokes a running application's initialization with OLE. (Use when application ends.) 
Vi2>


S>>... И еще, можно ли подсоединиться к активному объекту из VB ili VBScript?


Vi2>Можно.

Vi2>
Vi2>Dim obj As Object ' или Dim obj As ObjLib.ProgIDClass
Vi2>Set obj = GetObject(,"Obj.ProgID") ' сначала уже существующий
Vi2>If obj Is Nothing Then
Vi2>  Set obj = CreateObject("Obj.ProgID") ' если нет, пытаемся создать новый 
Vi2>End If
Vi2>


Vi2>Реальный пример

Vi2>
Vi2>Dim obj As Object ' или Dim obj As Word.Application
Vi2>Set obj = GetObject(,"Word.Application") ' сначала уже существующий Word
Vi2>If obj Is Nothing Then
Vi2>  Set obj = CreateObject("Word.Application") ' если нет, пытаемся запустить новый Word
Vi2>End If
Vi2>


tak ved' u menia GetObject uje sam i sozdaet ego esli on eshe ne sozdan zachem je eshe potom Create delat' ?

Set o_Obj = GetObject("", "Obj.ProgID")
X
Re[3]: Active Objects
От: Vi2 Удмуртия http://www.adem.ru
Дата: 25.07.02 08:30
Оценка: 3 (1)
Здравствуйте Sero, Вы писали:

S>tak ved' u menia GetObject uje sam i sozdaet ego esli on eshe ne sozdan zachem je eshe potom Create delat' ?

S>Set o_Obj = GetObject("", "Obj.ProgID")

Твой вариант будет создавать всегда новый экземпляр объекта Obj.ProgID, даже если уже работают несколько подобных активных (т.е. зарегистрированных в системе) объектов Obj.ProgID. Таково свойство вызова GetObject("", "Obj.ProgID") с первым параметром, равным "".

Если использовать GetObject(, "Obj.ProgID"), т.е. не передавать в первый параметр ничего, то либо вернётся ошибка, если в системе нет активных объектов Obj.ProgID, либо вернётся один (какой-то!) из них.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: Active Objects
От: Sero США  
Дата: 25.07.02 12:37
Оценка:
Здравствуйте Vi2, Вы писали:

Vi2>Твой вариант будет создавать всегда новый экземпляр объекта Obj.ProgID, даже если уже работают несколько подобных активных (т.е. зарегистрированных в системе) объектов Obj.ProgID. Таково свойство вызова GetObject("", "Obj.ProgID") с первым параметром, равным "".



Daaa, kak je ja ne zametil, eto v MSDN e
no, no...

no pochemu to
Set obj = GetObject(, "prgID")

ne prosto vozvrashaet
Nothing


, a generiruet Error kotori' Abortiruet programmu


i esli prochitat' MSDN( GetObject Function, VBScript) do konca to:


If an object has registered itself as a single-instance object, only one instance of the object is created, no matter how many times CreateObject is executed. With a single-instance object, GetObject always returns the same instance when called with the zero-length string ("") syntax, and it causes an error if the pathname argument is omitted.

a u menia kak raz taki ActiveObject kotori' Register itself as single instance


void CObj::UpdateRegistry()
{
    COleObjectFactory::UpdateRegistry("OBJ.PROGID");

    m_pDisp = GetIDispatch(FALSE);
    m_pDisp->QueryInterface(IID_IUnknown,(void **)&m_pUnk);
    HRESULT hr = RegisterActiveObject(m_pUnk, IID_IBuffer, ACTIVEOBJECT_WEAK, &m_lRegister);
    ::CoLockObjectExternal(m_pUnk, TRUE, TRUE);
}





chto je delat'
esli ostavit' kak signle object, no vizivat'
CreateObject("progid")

..ili
GetObject("", "progid")

chto kak vijasnilos' v dannom sluchae toje samoe
vse ravno sozdaetsia dva ob'ekta (dlia dostupa iz programmi k etomu objectu ja sozdaiu global'ni' ekzempliar ob'ekta kotori' sozdaetsia snachala, a VB ne Get aet ego a vse ravno sozdaet svo'

...
mojet ja nepravil'no sozdaiu signle object ?


mojno konechno prosto' obj'ect registrirovat' i vizivat' GetObject(, "prgid"), no prosto interesno
X
Re[5]: Active Objects
От: Vi2 Удмуртия http://www.adem.ru
Дата: 25.07.02 13:45
Оценка: 3 (1)
Здравствуйте Sero, Вы писали:

S>no pochemu to

S>Set obj = GetObject(, "prgID")
S>ne prosto vozvrashaet Nothing
S>, a generiruet Error kotori' Abortiruet programmu

Так, естстественно, СОМ функция возвращает код ошибки в отличие успешного завершения — ведь объекта она не имеет.
Должна быть обработка ошибок On Error Resume Next или On Error Goto ХХХХ.

S>i esli prochitat' MSDN( GetObject Function, VBScript) do konca to:


S>If an object has registered itself as a single-instance object, only one instance of the object is created, no matter how many times CreateObject is executed. With a single-instance object, GetObject always returns the same instance when called with the zero-length string ("") syntax, and it causes an error if the pathname argument is omitted.


Это песня другая. Такие объекты называются синглетонами и фактическая реализация может привести к такой ситуации: синглетоны могут и не регистрироваться в системе (тогда GetObject(, "prgID") будет возвращать ошибку. Ну нет такого объекта, что тут поделать!), а GetObject("", "prgID") как и CreateObject("prgID") будут возвращать указатель на один и тот же объект.

Т.е. синглетонами называют объекты, для которых не существует механизма создания второго и т.п. экземпляра, т.е. существует только один. Твой объект уж точно не такой (см. ниже).

S>a u menia kak raz taki ActiveObject kotori' Register itself as single instance


S>void CObj::UpdateRegistry()
S>{
S>    COleObjectFactory::UpdateRegistry("OBJ.PROGID");

S>    m_pDisp = GetIDispatch(FALSE);
S>    m_pDisp->QueryInterface(IID_IUnknown,(void **)&m_pUnk);
S>    HRESULT hr = RegisterActiveObject(m_pUnk, IID_IBuffer, ACTIVEOBJECT_WEAK, &m_lRegister);
S>    ::CoLockObjectExternal(m_pUnk, TRUE, TRUE);
S>}


Это реализация регистрации в системе, т.е. твой объект становится активным объектом.

S>mojno konechno prosto' obj'ect registrirovat' i vizivat' GetObject(, "prgid"), no prosto interesno


В уазанном тобой коде ты и реализовываешь вариант: если клиенту нужен активный объект, он должен запросить его по GetObject(, "prgid"), если же такого нет, то запускается новый или через GetObject("", "progid") или через CreateObject("progid").

Если ты в клиенте делаешь вызов GetObject("", "progid") или CreateObject("progid"), то новый объект принудительно создаётся — запрашивается его класс-фактору, которая и генерит новый экземпляр. Возникнет второй активный объект. О чём ты и пишешь:

S>vse ravno sozdaetsia dva ob'ekta (dlia dostupa iz programmi k etomu objectu ja sozdaiu global'ni' ekzempliar ob'ekta kotori' sozdaetsia snachala, a VB ne Get-aet (по GetObject("", "progid")) ego a vse ravno sozdaet svo'


S>chto je delat'?


Использовать код, который я приводил в начале — сначала GetObject(, "prgid"), а потом GetObject("", "progid").
Или перейти на реальный синглетон.

S>mojet ja nepravil'no sozdaiu signle object ?


Нужно как-то изменить поведение класс-фактори для твоего объекта. Я — не спец по МФС, поэтому не смогу тебе помочь реально.

Лучше посмотреть или форум МФС, или этот форум на предмет создания синглетонов в МФС.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Active Objects
От: Sero США  
Дата: 25.07.02 14:44
Оценка:
Здравствуйте Vi2, Вы писали:

Spasibo za soderjatel'ni' otvet.non voznikaut koe kakie novie :)

Vi2>Это песня другая. Такие объекты называются синглетонами и фактическая реализация может привести к такой ситуации: синглетоны могут и не регистрироваться в системе (тогда GetObject(, "prgID") будет возвращать ошибку. Ну нет такого объекта, что тут поделать!), а GetObject("", "prgID") как и CreateObject("prgID") будут возвращать указатель на один и тот же объект.


Tak znachit registratia v ROT e, kak Active Object eto ne est' singleton ?, to est' dlia singletonov est' svoi funkcii, API ili classi MFC ili ATL, ili mojet bit' eto nado vruchnuiu realizovivat' ?
A mojet prosto nado Active Object registrirovat' a pri sozdanii v fabrike classa prosto ego Get tat' odtuda, ?


To est' ja ponial tak chto mo' ob'ekt aktivni' v otlichie ot neaktivnogo obichnogo no vsio ravno on ne singleton i ego sleduet vizivat' imenno GetObject(,"progid") om esli xotim chtob on bil odin edinstvenni'

S>>vse ravno sozdaetsia dva ob'ekta (dlia dostupa iz programmi k etomu objectu ja sozdaiu global'ni' ekzempliar ob'ekta kotori' sozdaetsia snachala, a VB ne Get-aet (по GetObject("", "progid")) ego a vse ravno sozdaet svo'


Znachit li sozdanie odnogo edinstvennogo ob'ekta po visheobsujdennim metodam to, chto esli daje programma (server) global'no v sebe sozdast etot ob'ekt i zaregistriruet ego
BOOL CMyApp::InitInstance()
{
    o_Obj.UpdateRegistry();
    COleObjectFactory::UpdateRegistryAll();
    COleTemplateServer::RegisterAll();
}

to potom sozdannie, to est' naoborot ne sozdannie a Get nutie instansi ne budut kopiami, a budet vsego odin ob'ekt


Vi2>Нужно как-то изменить поведение класс-фактори для твоего объекта. Я — не спец по МФС, поэтому не смогу тебе помочь реально.

Vi2>Лучше посмотреть или форум МФС, или этот форум на предмет создания синглетонов в МФС.

a mojno li vkliuchit' ATL sozdanie signletona v proekt na MFC, ili on trebuet chego to svoego v osnove proekta ?
prosto vremeni net perexodit' na ATL seichas, dlia etogo proekta, nado prosto zakonchit'


Navernoe mne luchshe sdelat' prosto' ob'ekt , i vizivat' ego s pomoshiu GetObject(,"progid"), mne ved' vajno tol'ko chtob on bil odin , i ne ochen' interesno delat' ego activnim ili eshe kakim to
X
Re[7]: Active Objects
От: Vi2 Удмуртия http://www.adem.ru
Дата: 25.07.02 15:39
Оценка: 3 (1)
Здравствуйте Sero, Вы писали:

S>Tak znachit registratia v ROT e, kak Active Object eto ne est' singleton ?


Да. Регистрация в ROT не приводит к тому, что объект в действительности синглетон, т.к. запрос на новый объект будет порождать новый экземпляр. Т.е. синглетон определяется характером его класс-фактори. Вполне возможно, что класс-фактори воспользуется ROT-ом для передачи не нового, а уже активного объекта (вот это одна из разновидностей синглетона!), но обычные класс-фактори этим качеством не обладают.

S>, to est' dlia singletonov est' svoi funkcii, API ili classi MFC ili ATL, ili mojet bit' eto nado vruchnuiu realizovivat' ?

S>A mojet prosto nado Active Object registrirovat' a pri sozdanii v fabrike classa prosto ego Get tat' odtuda, ?

Вот-вот.

S>To est' ja ponial tak chto mo' ob'ekt aktivni' v otlichie ot neaktivnogo obichnogo no vsio ravno on ne singleton i ego sleduet vizivat' imenno GetObject(,"progid") om esli xotim chtob on bil odin edinstvenni'


Да.

S>Znachit li sozdanie odnogo edinstvennogo ob'ekta po visheobsujdennim metodam to, chto esli daje programma (server) global'no v sebe sozdast etot ob'ekt i zaregistriruet ego

S>BOOL CMyApp::InitInstance()
S>{
S>    o_Obj.UpdateRegistry();
S>    COleObjectFactory::UpdateRegistryAll();
S>    COleTemplateServer::RegisterAll();
S>}

S>to potom sozdannie, to est' naoborot ne sozdannie a Get nutie instansi ne budut kopiami, a budet vsego odin ob'ekt

Не совсем понял предложение. В твоём варианте GetObject(,"progid") вернёт именно тот же объект, который был зарегистрирован в RegisterActiveObject(m_pUnk,...). Может быть здесь моё непонимание МФС-шных функций сказывается. Я не знаю когда вызывается CObj::UpdateRegistry и что скрывается за всеми этими RegisterAll и т.п. Т.е. я реально не представляю процесс создания объектов в МФС, так, в общих чертах.

S>a mojno li vkliuchit' ATL sozdanie signletona v proekt na MFC, ili on trebuet chego to svoego v osnove proekta ?

S>prosto vremeni net perexodit' na ATL seichas, dlia etogo proekta, nado prosto zakonchit'

Ну, наверное, переходить не стоит. Но есть статья на эту тему Использование ATL для автоматизации MFC приложений
Автор(ы): Nick Hodapp
Дата: 15.07.2001
, в которой показано это дело.

Проще создать свой класс-фактори, который, может быть, порождается от COleObjectFactory и соотвественно ведёт себя как класс-фабрика синглетона. Или же вмешаться в процесс порождения COleObjectFactory объектов.
Как это сделать — МФС гуру тебе скажут. Я в этом не спец. Задай новый вопрос (поиск, наверное, ещё не работает. Но если работает, то ищи SINGLETON).

S>Navernoe mne luchshe sdelat' prosto' ob'ekt , i vizivat' ego s pomoshiu GetObject(,"progid"), mne ved' vajno tol'ko chtob on bil odin , i ne ochen' interesno delat' ego activnim ili eshe kakim to


Тут или я не понимаю тебя или ты меня.
1. При существующем у тебя механизме (с RegisterActiveObject и обычной класс-фактори) все клиенты должны использовать GetObject-потом-CreateObject, чтобы иметь один единственный экземпляр на всех. Если хотя бы один клиент выдаст CreateObject("prgID") без предварительного GetObject(,"progid"), то он получит ВТОРОЙ экземпляр из твоего сервера.

Тут есть проблема. Т.к. при определённых обстоятельствах, а именно: если несколько клиентов будут выполнять механизм GetObject-потом-CreateObject почти синхронно — будут создаваться вторые копии. Потому что некоторым клиентам GetObject вернёт код ошибки, если самый первый клиент еще не успел создать твой объект.

2. Есди ты изменишь только поведение класс-фактори, то клиенты могут обрашаться любым способом хоть GetObject(,"progid"), хоть CreateObject("prgID") — всё равно будут иметь один единственный экземпляр на всех.

3. Если же ты уберёшь RegisterActiveObject, но изменишь поведение класс-фактори на передачу одного глобального в твоём сервере объекта, то сервер должен быть EXE и все клиенты должны использовать только CreateObject("prgID"), чтобы иметь один единственный экземпляр на всех. Если клиенты выдадут запрос на GetObject(,"progid"), им вернётся код ошибки. В этом случае схема GetObject-потом-CreateObject также работает.

Поэтому, если написание клиентов в твоих руках, то смело вставляй код, который был вначале, и голову не забивай.
Если же нет, и в твоих руках только сервер, то прочитай статью и/или спроси как в МФС создают синглетоны.

PS
Всё это справедливо только для EXE серверов.Для DLL вообще проблематично использование синглетонов. Можно, конечно, но геморроя не в пример больше.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[8]: Active Objects
От: Sero США  
Дата: 25.07.02 17:46
Оценка:
Здравствуйте Vi2, Вы писали:

S>>Znachit li sozdanie odnogo edinstvennogo ob'ekta po visheobsujdennim metodam to, chto esli daje programma (server) global'no v sebe sozdast etot ob'ekt i zaregistriruet ego

S>>to potom sozdannie, to est' naoborot ne sozdannie a Get nutie instansi ne budut kopiami, a budet vsego odin ob'ekt

Vi2>Не совсем понял предложение. ...


ja imel vvidu chto esli est' server EXE, i class kotori' implementiruet interface ego ob'ekta kotori' tam est' v nem, , on kak bi derjid dannie kotorie nujni i klientu i serveru, odni i te je dannie, no server sam ne vizivaet svo' je ob'ekt po dispatch interfasu on prosto beret i sozdaet global'nuiu peremennuiu dlia etogo classa, snachala, mne nado bilo chtob VBScript client sviazivalsia s tem je ob'ektom chtob kak to umet' xranit' i peredavat' eti dannie v EXE, xotia na samom dele Script on toje javliaetsia serverom , eto script component, vobshem vse zaputano. Prosto kogda etot ob'ekt sozdaetsia global'no on ja nadeius' nichem ne otlichaetsia ot togo je og'ekta esli bi pervim ego sozdal Script po odno' iz izvestnix nam funkci'.

S>>Navernoe mne luchshe sdelat' prosto' ob'ekt , i vizivat' ego s pomoshiu GetObject(,"progid"), mne ved' vajno tol'ko chtob on bil odin , i ne ochen' interesno delat' ego activnim ili eshe kakim to

Vi2>Тут или я не понимаю тебя или ты меня.

Nu tut ja odnogo ne ponial , zachem vaabshe nujni eti ROT i i aktivnie ob'ekti esli singleton mojno realizovat' i bez nix.
No vaabshe ja imel vvidu chto ja mog bi sdelat' ili singleton estestvenno po fabrike klassa i prosto Creatat' ego ili je sdelat' obichnuiu fabriku i pol'zovatsia GetObjectom(, "prgid") , dlia moe' celi: imet' edinstveni' ekzempliar etogo ob'ekta, etix dvux metodov vpolne dostatochno.

Prosto naskol'ko ja znal ROT imenno dlia etogo bil nujen , chtob ego tam registrirovali pri sozdanii a pri , no pered etim proveriali esli uje on tam to prosto brali bi ego. Vse delo v tom chto sozdavalos' 2 kopii ob'ekta etogo, i togo chto sozdavalsia fabriko' klassa kogda vizov shel iz Scripta, ja dumau tut est' i 3 variant, prosto nado pokopatsia v MFC i naiti kak izmenit' fabriku klassa tak chtob on snachala proverial potom sozdaval esli nado. navernoe eto sdelano no sdelano nepravil'no,
Tut voznikaet eshe odin vopros kotori' mojet bit' uje i bil , chem otlichaiutsia activnie ob'ekti singletoni s izmeneno' fabriko' klassa ot obichnix ob'ektov singletonov s izmenenno' fabriko' klassa. Tako' uj ja, poka do vsex detale' ne dokopaius' ne uspokaivaius'.

No informacia kotoruiu vi mne dali dostatochno chtob pokopatsia i pri'ti k kakim to vivodam, bol'shoe spasibo :)

Vi2>PS

Vi2>Всё это справедливо только для EXE серверов.Для DLL вообще проблематично использование синглетонов. Можно, конечно, но геморроя не в пример больше.

a vot eto ogorchaet, xotia i k delu ne otnositsia, ;)

p.s. navernoe vse taki izmenit' fabriku klassa chtob prevratit' ob'ekt v singleton eto i znachit vospol'zovatsia ROT om i ne kak po drugomu , jal' segodnia uje vremeni net pridetsia zavtra proveriat'
X
Re[9]: Active Objects
От: Vi2 Удмуртия http://www.adem.ru
Дата: 26.07.02 04:05
Оценка: 3 (1)
Здравствуйте Sero, Вы писали:

S>Я имел ввиду что если есть сервер EXE, и класс который имплементирует интерфейс э(то)го объекта кторый там есть в нём, , он как бы держит данные которые нужны и клиенту и серверу, одни и те же данные, но сервер сам не вызывает свой же объект по dispatch интерфейсу он просто берёт и создаёт глобальную переменную для этого класса, сначала, мне надо было чтоб VBScript клиент связывался с тем же объектом чтоб как-то уметь хранить и передавать эти данные в EXE, хотя на самом деле Script он тоже является сервером , это script компонент, вобщем всё запутано. Просто когда этот объект создаётся глобально он я надеюсь ничем не отличается от того же объекта если бы первым его создал Script по одной из известных нам функций.


Пришлось покопаться в МФС, чтобы немного понять их механизм и чтобы что-то посоветовать. Но я не уверен — практики нет.

Похоже, что создание объектов в МФС делается через DECLARE_OLECREATE/_EX и т.п. макросы. А создающий метод в МФС класс-фактори COleObjectFactory::OnCreateObject, которая является виртуальной. Поэтому вот такое изменение, надеюсь, приведёт к желаемому результату.
В твоём классе нужно воспользоваться вместо DECLARE_OLECREATE/_EX макросами BEGIN_OLEFACTORY и END_OLEFACTORY, позволяющим ввести свою обработку. А также обеспечить динамическое создание CYourMFCClass* global_ptr, расположенного глобально или статически в классе и нужного для доступа внутри сервера, при запуске твоего приложения.

... CYourMFCClass ... 
{
// вместо DECLARE_OLECREATE(CYourMFCClass) или DECLARE_OLECREATE_EX(CYourMFCClass)
    BEGIN_OLEFACTORY(CYourMFCClass)

    CCmdTarget* OnCreateObject() // смотри CCmdTarget* COleObjectFactory::OnCreateObject()
    {
        if( global_ptr != NULL ) // уже создан динамически
            return global_ptr;

        // allocate object, throw exception on failure
        global_ptr = (CYourMFCClass*)m_pRuntimeClass->CreateObject();
        if (CYourMFCClass == NULL)
            AfxThrowMemoryException();

        // здесь можно и зарегистрировать в ROT для возможности получения активного объекта

        // return the new CYourMFCClass object
        return global_ptr ;
    }

    END_OLEFACTORY(CYourMFCClass)
...
};

Ещё одно требование: нужно сделать — чтобы регистрация класс-фактори была настроена на создание множественных экземпляров на одно приложение (аналогия с MDI). Обычные макросы МФС настроены на создание одного экземпляра на приложение. Поэтому нужно каким-то образом изменить поле m_bMultiInstance твоеё класс-фактори. Или создать макрос, похожий на IMPLEMENT_OLECREATE_EX, но только вместо FALSE чтобы было TRUE.
#define IMPLEMENT_OLECREATE_EX(class_name, external_name,             l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)     const TCHAR _szProgID_##class_name[] = _T(external_name);     AFX_DATADEF class_name::class_name##Factory class_name::factory(         class_name::guid, RUNTIME_CLASS(class_name), FALSE,         _szProgID_##class_name);


S>Ну тут я одного не понял , зачем вообще нужны эти ROT-ы и активные объекты если singleton можно реализовать и без них.

S>Но вообще я имел ввиду что я мог бы сделать или singleton естесственно по фабрике класса и просто Create-ить его или же сделать обычную фабрику и пользоваться GetObject(, "prgid") , для моей цели: иметь единственный экземпляр этого объекта, этих двух методов вполне достаточно.
S>Просто насколько я знал ROT именно для этого был нужен , чтоб его там регистрировать при создании а при , но перед этим проверяли если уже он там то просто брали бы его. Все дело в том что созавалось 2 копии объекта этого, и того что созавался фабрикой класса когда вызов шёл из Scripta, я думаю тут есть и 3 вариант, просто надо покопаться в МФС и найти как изменить фабрику класса так чтоб он сначала проверял потом создавал если надо. Наверное это сделано но сделано неправильно.

S>Тут возникает ещё один вопрос который может быть уже и был , чем отличается активные объекты singleton-ы с изменённой фабрикой класса от обычных объектов singleton-ов с изменённой фабрикой класса. Такой уж я, пока до всех деталей не докопаюсь не успокаиваюсь.


Ничем по функциональности, только первый ещё доступен через ROT и тем, что его оттуда нужно удалять после завершения работы, что иногда забывается или не получается(аварийное снятие приложения).

S>Но информация которую вы мне дали достаточно чтоб покопаться и приёти к каким-то выводам, большое спасибо :)


S>p.s. наверное всё-таки изменить фабрику класса чтоб превратить объект в singleton это и значит воспользоваться ROT-ом и не как по-другому , жаль сегодня уже времени нет придётся завтра проверять.


А вот тут ты не прав! Пользование ROT-ом — это не единственное решение, к тому же оно не сможет выручить без синхронизации при почти одновременных запросах объекта. Выше я привёл пример, как без ROT создаётся один объект.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.