С Новым годом! Форум программистов, компьютерный форум, киберфорум
C/C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/40: Рейтинг темы: голосов - 40, средняя оценка - 4.88
2 / 2 / 3
Регистрация: 02.12.2014
Сообщений: 75
1

Использование функций CoInitialize и CoUnitialize в контексте глобальных параметров

28.08.2015, 16:24. Показов 7472. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет,

Интересует вопрос использования функций (CoInitialize и CoUnitialize) в контексте инициализации и уничтожения глобальных объектов COM. Например, есть набор параметров, которые извлекаются в глобальные переменные до момента завершения приложения. Пара (CoInitialize и CoUnitialize) необходима для инициализации COM объектов, но когда есть промежуточные функции, которые используют те же глобальные объекты COM, не получается ли так, что использование данной пары лишним? Вот так выглядит код:
plugin.h
C++
1
2
3
4
5
6
#import "h:\INSITU\kdsdk.dll" auto_rename no_namespace
 
// Smart pointer
_AppliPtr app(__uuidof(Appli));
_ScenePtr scn(__uuidof(Scene));
_CatalogPtr cat(__uuidof(Catalog));
plugin.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
bool Plugin::OnAppStartAfter(long CallParamBlock)
{
    CoInitialize(NULL);
 
    // Initialized objects
 
    CoUninitialize();
    return 1;
}
 
bool Plugin::OnAppQuitBefore(long CallParamBlock)
{
    CoInitialize(NULL);
 
    // Destroy objects
 
    CoUninitialize();
    return 1;
}
1. Если удалить функции (CoInitialize и CoUnitialize) то программа работает без ошибок. Не является ли бессмысленным использованием данной пары, когда объекты COM создаются на основе Smart Pointer?
2. Если все же необходимо использовать пару (CoInitialize и CoUnitialize), то возможно использовать такую конструкцию:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool Plugin::OnAppStartAfter(long CallParamBlock)
{
    CoInitialize(NULL);
 
    // Initialized objects
 
    return 1;
}
 
bool Plugin::OnAppQuitBefore(long CallParamBlock)
{
 
    // Destroy objects
 
    CoUninitialize();
    return 1;
}
то есть, CoInitialize на момент старта приложения, и CoUninitialize на момент завершения, или данный метод недопустим?
Спасибо
1
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.08.2015, 16:24
Ответы с готовыми решениями:

Задача на использование функций в качестве параметров других функций
Составить программу по заданному условию. Первая часть условия является заданием на разработку...

Объявление глобальных в контексте приложения переменных
Создаю проект в vc++ 2010. Прога содержит множество форм, в которых производятся манипуляции с БД...

Использование функций в качестве формальных параметров
Помогите вычислить f(x)/g(x), где в качестве f(x) и g(x) могут быть четыре различные функции,...

С++ Использование функций как параметров процедур
Процедура Р формирует массив из элементов Z, для которых одновременно выполняются условия F1( Z)>C,...

8
Ушел с форума
Эксперт С++
16478 / 7441 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
28.08.2015, 20:45 2
Лучший ответ Сообщение было отмечено Vite как решение

Решение

Во-первых, CoInitialize/Uninitialize работают по принципу подсчета ссылок:
X раз вызвали init, X раз нужно вызвать uninit. Главное, чтобы аргументы
вызова всегда были одинаковыми.

Во-вторых, COM-объекты без CoInitialize использовать вообще нельзя,
так что сомнения беспочвенны.

Ну и в-третьих, если глобальные объекты находятся в dll и им нужна
COM-инициализация - это уже очень плохо.
0
2 / 2 / 3
Регистрация: 02.12.2014
Сообщений: 75
28.08.2015, 21:32  [ТС] 3
То есть, для каждой функции, где вызываются объекты COM нужно использовать пару (CoInitialize/Uninitialize).

Спасибо за поддержку
0
Ушел с форума
Эксперт С++
16478 / 7441 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
28.08.2015, 21:49 4
Правильнее не для функции, а для потока.
Один поток, использующий COM - одна пара CoInitialize/CoUninitialize.
0
2 / 2 / 3
Регистрация: 02.12.2014
Сообщений: 75
28.08.2015, 22:11  [ТС] 5
Цитата Сообщение от Убежденный Посмотреть сообщение
Правильнее не для функции, а для потока.
Один поток, использующий COM - одна пара CoInitialize/CoUninitialize.
Значит мое предположение верно, использовать CoInitialize при запуске приложения, и CoUninitialize перед завершением. Если я ошибаюсь, поправьте меня.
0
Ушел с форума
Эксперт С++
16478 / 7441 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
28.08.2015, 22:31 6
CoInitialize(Ex)/OleInitialize должен быть вызван в каждом потоке
перед тем, как поток будет работать с COM. Вот основное правило.
Если у тебя двадцать потоков и каждый где-то делает CoCreateInstance и
т.п., то каждый из них должен звать CoInitialize(Ex).
2
2 / 2 / 3
Регистрация: 02.12.2014
Сообщений: 75
28.08.2015, 22:46  [ТС] 7
Ну, мне пока рановато до распределенных систем. Все происходит в едином процессе приложения, по этому я решил оптимизировать код, используя пару (CoInitialize/CoUninitialize) в специальных функциях SDK приложения.

Вот только один момент до конца не понятен, если создается глобальный объект в заголовке, например:
C++
1
_AppliPtr app(__uuidof(Appli));
Данный объект можно считать созданным, или пока он не будет инициализирован, не является объектом?
0
Ушел с форума
Эксперт С++
16478 / 7441 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
28.08.2015, 22:53 8
Цитата Сообщение от Vite Посмотреть сообщение
Ну, мне пока рановато до распределенных систем. Все происходит в едином процессе приложения
Vite, ну при чем здесь распределенные системы ?


Вот смотри, приведу пример, может так нагляднее будет:
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
32
#include <Windows.h>
 
DWORD WINAPI ThreadProc(PVOID Arg)
{
    CoInitialize(NULL);
 
    //
    // Этот поток тоже хочет использовать COM,
    // поэтому он тоже должен вызывать эти функции.
    //
 
    // Здесь какие-то операции с COM - CoCreateInstance и т.п.
 
    CoUninitialize();
    return 0;
}
 
int main()
{
    HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
    CloseHandle(hThread);
 
    CoInitialize(NULL);
 
    //
    // Тут работаем с COM-объектами, вызываем другие функции,
    // уходим далеко вглубь и т.д.
    //
 
    CoUninitialize();
    return 0;
}
0
2 / 2 / 3
Регистрация: 02.12.2014
Сообщений: 75
28.08.2015, 23:22  [ТС] 9
В моем случае, объекты COM инициализированы только в функциях (SDK) приложения. Практически все функции SDK использую параметр SessionId, который определен в глобальной переменной. То есть на момент старта приложения, вызывается функция OnAppStartAfter, в которой определяется параметр SessionId, и он неизменный до завершения приложения. В этом смысле, как я понимаю, поток единый.
0
28.08.2015, 23:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.08.2015, 23:22
Помогаю со студенческими работами здесь

Использование значений, заданных по умолчанию для параметров функций
Прочтено в учебнике &quot;Джесс Либерти. Си++ за 21 день&quot;. Мол, затерев значения переменной в главной...

Обработать одномерный массив с использование процедур и функций без параметров и с параметрами
После первого элемента вставить 0 Обработать одномерный массив с использование процедур и функций...

Обработать одномерный массив с использование процедур и функций без параметров и с параметрами
Обработать одномерный массив с использование процедур и функций без параметров и с...

Потокозащищенность глобальных функций .NET
Подскажите пожалуйста, имеется программа, запускаются два потока и в обоих потоках используется...


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

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