быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
1

Транслируются ли аргументы функции CoCreateInstance в аргументы функции DllGetClassObject?

22.03.2013, 17:40. Показов 3685. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
НУ то есть я думаю должно быть понятно, о чём речь. В клиенте вызывается функция:

C++
1
2
3
4
5
6
7
CoCreateInstance (
REFCLSID,
аргумент__2,
аргумент__3
REFIID,
void**
);
Речь идё о первом, четвёртом и пятом аргументах. Вроде как они точно должны соответствовать Этим аргументам:

C++
1
STDAPI DllGetClassObject(const GUID& Guid, const GUID& Iid, void ** ppv){;}
Тем более, что тут написано:

Для того, чтобы система выяснила какой сервер необходимо активизировать (просмотрев системный реестр), загрузила его, и вызвала у этого сервера функцию DllGetClassObject клиент на своей стороне вызывает "широко известную в узких кругах" функцию Win32 API CoCreateInstance - создать экземпляр объекта. MSDN дает о ней следующую справку:

STDAPI*CoCreateInstance(
REFCLSID*rclsid, //CLSID объекта класса
LPUNKNOWN*pUnkOuter,
DWORD*dwClsContext,
REFIID*riid, //Ссылка на идентификатор интерфейса, который взаимодействует с объектом LPVOID***ppv //Адрес выходной переменной, которая принимает указатель на интерфейс, указанный riid );

Аргументы pUnkOuter и dwClsContext в данный момент нас не интересуют, они указывают системе среди DLL или EXE-серверов искать интересующий нас объект и агрегировать ли его. А вот три других аргумента - в точности те, которые передаются системой функции сервера DllGetClassObject. И - функцию CoCreateInstance клиент вызывает из своего кода. Иными словами - вызов клиентом функции CoCreateInstance "транслируется" системой в вызов функции DllGetClassObject на стороне сервера. DllGetClassObject возвращает адрес объекта, система передает его CoCreateInstance, которая возвращает его клиенту. Всё, наша экскурсия в философию закончена - пункты с первого по четвёртый проиллюстрированы сущностями операционной системы.
НО я так считаю, что это бред сивой кобылы. Аргумент REFIID функции CoCreateInstance соответствует аргументу REFIID функции CoCreateInstance как свинья апельсинам. Если кто возразит, приведу доказательства.

Если возражений не будет, тогда вопрос- почему так? Вроде как должен соответствовать-то! Иначе какой смысл в вызове CoCreateInstance с точно определённым четвёртым параметром, если на выходе (точнее- при вызове DllGetClassObject) он преобразуется в невесть что?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.03.2013, 17:40
Ответы с готовыми решениями:

Создание функции, формирующую предложение из аргументов функции, аргументы . Аргументы - переменное число
Короче, вот бы всё норм. Хочу соединять, но он мне выдаёт ошибку, когда использую strcat. Не могу...

Аргументы функции: что значит "большие" и "небольшие" аргументы?
Здравствуйте! Всем доброго дня! Растолкуйте пожалуйста! Что значит большие и небольшие?

Аргументы функции
Доброго времени суток. Есть функция очистки переменных посредством mysql_real_escape_string. В ней...

Аргументы функции
Добрый день. Столкнулся с проблемой передачи аргументов в функцию. У меня есть матрица, которую я...

17
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
23.03.2013, 19:25  [ТС] 2
Чё, никто не задумывался над этим что ли?

Короче, я делаю вывод, что это просто-напросто ошибка автора. Ещё раз: аргументы CoCreateInstance НЕ ТРАСЛИРУЮТСЯ в аргументы DllGetClassObject (чего не скажешь про аргументы CoGetClassObject)
0
Модератор
3398 / 2170 / 352
Регистрация: 13.01.2012
Сообщений: 8,400
25.03.2013, 09:23 3
Цитата Сообщение от kravam Посмотреть сообщение
Чё, никто не задумывался над этим что ли
вы сами то пробовали реализовать и посмотреть что будет? или работаем на кончике пера? вот реализация функции и последующий вызов создающий объект. попробуйте ответить на свой вопрос, а то я его не очень пойму.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
HRESULT __stdcall __export DllGetClassObject(
    REFCLSID rclsid, REFIID riid, void **ppvObject)
{
    sys_log.printf("DllGetClassObject\n");
 
    HRESULT res = CLASS_E_CLASSNOTAVAILABLE;
 
    if (rclsid == CLSID_CoMyObject)
    {
        CoMyObjectClassFactory *p = new(std::nothrow) CoMyObjectClassFactory;
        if (!p) return E_OUTOFMEMORY;
 
        res = p->QueryInterface(riid, ppvObject);
        if (FAILED(res)) delete p;
    }
 
    return res;
}
...
IMyObject *pi;
CoCreateInstance
(
    CLSID_CoMyObject, 0, context, IID_IMyObject,
    (LPVOID *)&pi
);
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
25.03.2013, 10:47 4
Цитата Сообщение от kravam Посмотреть сообщение
Если кто возразит, приведу доказательства.
ну давай, приводи.
CoCreateInstance создает компонент через фабрику, у Роджерсона(Основы Ком) можно посмотреть примерную реализацию.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
25.03.2013, 11:45  [ТС] 5
Цитата Сообщение от vxg Посмотреть сообщение
вы сами то пробовали реализовать и посмотреть что будет?
а то. А вы специально пишите страшные слова типа sys_log, CoMyObjectClassFactory чтобы я на них отвлёкся?

Цитата Сообщение от Jupiter Посмотреть сообщение
ну давай, приводи.
Вот ПРОСТОЙ проект. Никаких слов-отвлекалок. Хидер, клиент, сервер. Чисто вывод четвёртого параметра CoCreateInstance, псле чего вывод второго параметра DllGetClassObject; эта функция в самом конце. Вот она, кстати ТОЛЬКО чтобы продемонстрировать её второй параметр:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//Эта функция просто преобразует последовательность байт в строку ANSI
//******************************************************************************
char* f (char* rez, char* src, int count) {
 for (int i= 0; i< count; i++ ) {
  unsigned char t;
  t= ((unsigned char)src[i])/0X10;
  t<10?(rez[i*2]= t+48):(rez[i*2]= t+ 55);
  t= ((unsigned char)src[i])%0X10;
  t<10?(rez[i*2+ 1]= t+48):(rez[i*2+ 1]= t+ 55);
 }
 rez [count*2]= 0;
 return rez;
}
 
 
 
//******************************************************************************
STDAPI DllGetClassObject(const GUID& Guid,
                         const GUID& Iid,
                         void ** ppv
                        ){
 
        char tmp__ [sizeof (GUID)* 2+ 1];
        f (tmp__, (char*)&Iid, sizeof (GUID));
        
        //ВЫвод Iid
        printf (tmp__);
        
        getchar (); 
  
}
Там ещё файл "компилить.txt", где написано, как компилить и два батника для регистрации и разрегистрации.
Вложения
Тип файла: rar проект.rar (3.0 Кб, 24 просмотров)
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
25.03.2013, 11:55  [ТС] 6
Цитата Сообщение от Jupiter Посмотреть сообщение
CoCreateInstance создает компонент через фабрику, у Роджерсона(Основы Ком) можно посмотреть примерную реализацию.
это второй вопрос чего она там создаёт, щас я хочу увидеть соответствие параметров её И DllGetClassObject

Добавлено через 8 минут
Дай-ка вывод напишу, а то не поверят ведь:
Bash
1
2
3
4
четвёртый параметр равен
  B25D9D3F1334D511AE3800E02944637A
, а в DllGetClassObject он чудесным образом становится равным...
  0100000000000000C000000000000046
0
Модератор
3398 / 2170 / 352
Регистрация: 13.01.2012
Сообщений: 8,400
25.03.2013, 11:58 7
Цитата Сообщение от kravam Посмотреть сообщение
А вы специально пишите страшные слова типа sys_log, CoMyObjectClassFactory чтобы я на них отвлёкся
просто выдернуто прямо из дымящегося камня)
не понимаю что должен показать ваш пример. мой пример корректно работает создавая все что нужно в соответствии с переданными аргументами нисколько их не искажая. чудес не бывает. поясните на что вы хотите открыть нам глаза.

Добавлено через 1 минуту
Цитата Сообщение от kravam Посмотреть сообщение
а то не поверят ведь
да, не верим. наверное в вашей функции вывода ошибка в отладчике пробовали смотреть?

Добавлено через 1 минуту
попробуйте вываливать GUID на экран чем то таким
C++
1
2
3
4
5
6
7
8
std::wstring guid_to_wstr(const GUID &guid)
{
    LPOLESTR ws = 0;
    StringFromCLSID(guid, &ws);
    std::wstring res = ws;
    CoTaskMemFree(ws);
    return res;
}
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
25.03.2013, 12:00  [ТС] 8
Цитата Сообщение от vxg Посмотреть сообщение
да, не верим
То есть я правильно понял что вы запускать не запускали, но не верите? Типа: "не читал, но осуждаю?"
Вот запустите и убедитесь сами. А потом дальше будем разговаривать. Так-то смешно: функция выводит то, чего не ожидалось, значит, функция неверна. Гениально. А может на вход не то подано?
0
Модератор
3398 / 2170 / 352
Регистрация: 13.01.2012
Сообщений: 8,400
25.03.2013, 12:24 9
ага. из exe уходит ваш IID, а в DLL приходит IID IUnknown. потом система сама через QueryInterface получает ваш интерфейс и возвращает его в качестве результата вызова функции. не?

Добавлено через 37 секунд
ужасный лог:
==================================================
CoInitializeEx...
CoInitializeEx ok
CoInitializeSecurity
CoInitializeSecurity ok
CoMyObjectClassFactory::ctor
CoRegisterClassObject...
CoMyObjectClassFactory::AddRef
CoMyObjectClassFactory::AddRef
CoMyObjectClassFactory::QueryInterface (iid = {00000001-0000-0000-C000-000000000046}, iname = IClassFactory)
CoMyObjectClassFactory::AddRef
CoMyObjectClassFactory::Release
CoMyObjectClassFactory::CreateInstance (iid = {00000000-0000-0000-C000-000000000046}, iname = IUnknown)
CoMyObject::ctor
CoRegisterClassObject ok
CoMyObject::QueryInterface (iid = {00000000-0000-0000-C000-000000000046}, iname = IUnknown)
CoMyObject::AddRef
CoMyObject::AddRef
CoMyObject::QueryInterface (iid = {00000003-0000-0000-C000-000000000046}, iname = N/A)
CoMyObject::QueryInterface (iid = {0000001B-0000-0000-C000-000000000046}, iname = N/A)
CoMyObject::QueryInterface (iid = {00000000-0000-0000-C000-000000000046}, iname = IUnknown)
CoMyObject::AddRef
CoMyObject::AddRef
CoMyObject::QueryInterface (iid = {00000018-0000-0000-C000-000000000046}, iname = N/A)
CoMyObject::QueryInterface (iid = {00000019-0000-0000-C000-000000000046}, iname = N/A)
CoMyObject::QueryInterface (iid = {4C1E39E1-E3E3-4296-AA86-EC938D896E92}, iname = N/A)
CoMyObject::Release
CoMyObject::QueryInterface (iid = {2B952F0A-8797-428C-8E18-5D037CFEBB1D}, iname = IMyObject)
CoMyObject::AddRef
CoMyObject::AddRef
CoMyObject::Release
CoMyObject::Release
CoMyObjectClassFactory::Release
CoMyObject::QueryInterface (iid = {1C733A30-2A1C-11CE-ADE5-00AA0044773D}, iname = N/A)
CoMyObject::QueryInterface (iid = {2B952F0A-8797-428C-8E18-5D037CFEBB1D}, iname = IMyObject)
CoMyObject::AddRef
CoMyObject::GetX
CoMyObject::GetX
CoMyObject::Release
CoMyObject::Release
CoMyObject::Release
CoMyObject::Release
CoMyObject::dctor
CoRevokeClassObject...
CoMyObjectClassFactory::QueryInterface (iid = {00000003-0000-0000-C000-000000000046}, iname = N/A)
CoMyObjectClassFactory::QueryInterface (iid = {00000000-0000-0000-C000-000000000046}, iname = IUnknown)
CoMyObjectClassFactory::AddRef
CoMyObjectClassFactory::Release
CoMyObjectClassFactory::Release
CoMyObjectClassFactory::dctor
CoRevokeClassObject ok
CoUninitialize...
CoUninitialize ok
==================================================

Добавлено через 1 минуту
...попутно в некоторых случаях мы можем увидеть запрос всякого хлама вроде интерфейса маршаллера или вообще хрен пойми чего. да, такая у нас система, любопытная она
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
25.03.2013, 12:30  [ТС] 10
Так чё ага-то? Я понимаю, что там много чего вызывается. И не просто так в DllGetClassObject приходит IID_IUnknown, значит надо так. С этим-то что делать?:
три других аргумента - в точности те, которые передаются системой функции сервера DllGetClassObject.
списываем на ошибку автора?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
25.03.2013, 13:16 11
Цитата Сообщение от kravam Посмотреть сообщение
С этим-то что делать?
да что хочешь то и делай, а верю Роджерсону и Троэльсону

Добавлено через 1 минуту

Не по теме:

А вы специально пишите страшные слова чтобы я на них отвлёкся?
Цитата Сообщение от kravam Посмотреть сообщение
C++
1
t<10?(rez[i*2]= t+48):(rez[i*2]= t+ 55);
убил:D
C++
1
rez[i * 2] = t < 10 ? t + 48 : t + 55



Добавлено через 4 минуты
Цитата Сообщение от kravam Посмотреть сообщение
а в DllGetClassObject он чудесным образом становится равным...
* 0100000000000000C000000000000046
а в DllGetClassObject он чудесным образом становится удивительно похожим на IID IClassFactory
0
Модератор
3398 / 2170 / 352
Регистрация: 13.01.2012
Сообщений: 8,400
25.03.2013, 13:36 12
Цитата Сообщение от kravam Посмотреть сообщение
списываем на ошибку автора
вы так об этом говорите, как будто он мост неправильно посчитал и люди погибли. спишем на ошибку перевода и вашу дотошность при анализе предложения великого русского языка.
Цитата Сообщение от Jupiter Посмотреть сообщение
а в DllGetClassObject он чудесным образом становится удивительно похожим на IID IClassFactory
кстати, да
таким образом - об чем сыр бор?
0
Jupiter
25.03.2013, 13:40
  #13

Не по теме:

Цитата Сообщение от vxg Посмотреть сообщение
таким образом - об чем сыр бор?
а хз:D

0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
25.03.2013, 13:57  [ТС] 14
Цитата Сообщение от vxg Посмотреть сообщение
спишем на ошибку перевода и вашу дотошность при анализе предложения великого русского языка.
Так он русский... Он Михаил Безверхов. И он автор

Цитата Сообщение от vxg Посмотреть сообщение
кстати, да
таким образом - об чем сыр бор?
Действительно было
3F9D5DB2-3413-11d5-AE38-00E02944637A
стал
0100000000000000C000000000000046, то есть IClassFactory

А не должно было стать. Чему удивляться, действительно...
Вот об этом и сыр бор, почему он стал IClassFactory. То, что он стал IClassFactory я и сам знаю. И оно не "кстати да." Оно ничё не объясняет. Ещё раз: я понимаю, что раз оно становится IClassFactory значит, так и надо. Но что делать с цитатой?

мнение Jupiterа мне известно- "ой не трогайте меня, вы поколеблите мои устои даже читать ничё не буду. И да, константа эта называется IClassFactory" И считает что всё объяснил. Гениально, чё сказать.
0
Модератор
3398 / 2170 / 352
Регистрация: 13.01.2012
Сообщений: 8,400
25.03.2013, 14:35 15
Цитата Сообщение от kravam Посмотреть сообщение
значит, так и надо
именно так. DllGetClassObject используется для получения объекта который будет штамповать объекты, т.е. фабрики классов. вот, например,
http://msdn.microsoft.com/ru-R... s.85).aspx
(хотя там и написано "Usually, this is IID_IClassFactory" я думаю правильнее было бы написать "если вы в своем уме то это должна быть фабрика классов" потому как иначе ломается вся задумка. затрудняюсь ответить что будет делать CoCreateInstance если не найдет фабрику. мб запросит IUnknown, или даже запрашиваемый пользователем интерфейс, но я думаю рухнет. сейчас попробую )

Добавлено через 10 минут
да, упала. лог вот такой
=======================
DLL_PROCESS_ATTACH
DllGetClassObject
CoMyObject::ctor
CoMyObject::QueryInterface (iid = {00000001-0000-0000-C000-000000000046}, iname = IClassFactory)
CoMyObject::dctor
DLL_PROCESS_DETACH
=======================
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
25.03.2013, 14:49  [ТС] 16
Ну пусть так.
Дело-то ещё в том, что по факту DllGetClassObject (если вызывается CoCreateInstance) не нужна ВООБЩЕ.
Ну то есть как не нужна- ну да, при вызове CoCreateInstance и отсутствии DllGetClassObject программа рухнет наверное, я не спорю. Но сделайте DllGetClassObject просто для проформы- лишь бы возвращала корректное значение и всё, CoCreateInstance нормально отработает.

А раз так, то вывод: можно было бы всё это замутить так, чтобы COM-объект работал вообще без DllGetClassObject (при условии использования CoCreateInstance). Но это конечно дело тех, кто придумал COM-объекты. Меня это щас мало интересует, это их дела. Просто такой вот фактик.

Я ведь так понимаю, что DllGetClassObject нужна, чтобы мы там вручную могли что-то написать. А если оно автоматом всё делается, то... вот

А как вы получаете такие логи?
0
Модератор
3398 / 2170 / 352
Регистрация: 13.01.2012
Сообщений: 8,400
25.03.2013, 14:55 17
Цитата Сообщение от kravam Посмотреть сообщение
Дело-то ещё в том, что по факту DllGetClassObject (если вызывается CoCreateInstance) не нужна ВООБЩЕ.
Ну то есть как не нужна- ну да, при вызове CoCreateInstance и отсутствии DllGetClassObject программа рухнет наверное, я не спорю. Но сделайте DllGetClassObject просто для проформы- лишь бы возвращала корректное значение и всё, CoCreateInstance нормально отработает.
А раз так, то вывод: можно было бы всё это замутить так, чтобы COM-объект работал вообще без DllGetClassObject (при условии использования CoCreateInstance). Но это конечно дело тех, кто придумал COM-объекты. Меня это щас мало интересует, это их дела. Просто такой вот фактик.
Я ведь так понимаю, что DllGetClassObject нужна, чтобы мы там вручную могли что-то написать. А если оно автоматом всё делается, то... вот
волосы дыбом. вы не получите ничего если DllGetClassObject не отрабатывает корректно. вы можете 100 раз обманывать систему возвращая S_OK, но никаких объектов из воздуха не создастся - они генерируются именно фабрикой которую система не может получить ниоткуда кроме как из DllGetClassObject. логи получаются той самой надписью которая вас напугала. вот здесь
https://www.cyberforum.ru/com-... 63368.html
лежит com_server_test (clear).rar - играйте с ним и глядите что происходит
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,680
26.03.2013, 23:26  [ТС] 18
Был неправ.

Добавлено через 4 часа 13 минут
А вот три других аргумента - в точности те, которые передаются системой функции сервера DllGetClassObject.
через несколько глав
На самом деле, принимая на вход CLSID-IID, CoCreateInstance последовательно вызывает GoGetClassObject с аргументами CLSID-IClassFactory
а ты мучься...
0
26.03.2013, 23:26
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.03.2013, 23:26
Помогаю со студенческими работами здесь

Аргументы функции
Добрый вечер! Сразу по делу: int func(char s) {....} int main { char s; // s-символьная...

C++ аргументы функции
Извиняюсь за дилетантский вопрос. Допустим нужно передать string address = argv string...

Аргументы функции
Программа должна вычислять x-e число Фибоначчи по mod y. Вылетает ошибка, что передано слишком...

Аргументы у функции
void String(int i, int j, int N, double a) И компилятор студии 2010 выдает следующие ошибки:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru