@ProCxx

Страница 2468 из 2477
Vyacheslav
25.10.2018
10:03:25
MessageLoop в менюшке, например, свой, особенный и очень специфический
У вас уже есть костыли такого рода в программе, причем здесь COM?

Constantine
25.10.2018
10:03:48
У вас уже есть костыли такого рода в программе, причем здесь COM?
При том, что COM нарушает структуру владения и тем самым ломает все порядки жизни сущностей

Constantine
25.10.2018
10:04:00
Кто "он"?
Диалог

Google
Vyacheslav
25.10.2018
10:04:50
При том, что COM нарушает структуру владения и тем самым ломает все порядки жизни сущностей
Он упорядочивает структуру владения. Клиент(ы) контролируют время жизни всех СОМ объектов и только они.

Да, но в действительности не может жить под shared_ptr с продлением владения
Handle диалога не может жить под shared_ptr? Я не понимаю. В COM нельзя использовать shared_ptr для хранения указателей на COM объекты. Для этого есть CComPtr из ATL.

Отойду на обед. У кого тоже обед - приятного аппетита.

Constantine
25.10.2018
10:08:34
Как только у вас начинаются shared_ptr у вас вылетает нормальное RAII, все обертывается на Maybe и вообще становится очень приятно программировать И вот эта возникающая maybe-обертка в COM как раз проблема COM, а не структуры, к которой его подсоединяют

Потому что если структура выставляет четкое требование "объект внутри диалога никогда не переживет диалог", "порядок создания определяет порядок удаления" и "объект в невалидном состоянии не существует", у вас нет maybe-оберток и просто не бывает полувалидных объектов типа "диалог, который почему-то еще недоумер"

Timothy
25.10.2018
10:18:21
Супер. Как проще всего синхронно отправить сообщение другому процессу (WM_COPYDATA) и дождаться от него ответа (тоже WM_COPYDATA) ? нужно сделать что-то типа WaitForWMCopyData
Если нужна реентерабельность - то проще всего взять MS COM, делается всё просто (если с ATL), если не нужна - то как писалось - SendMessage

Ilia
25.10.2018
10:34:58
Igor
25.10.2018
10:54:56
Командой соответствующей
команда поиска это конечно шик, да conan search openssl: None found. эээ. а ну да, он же по умолчанию в кэше только ищет. conan search openssl -r all: None found. эээ. а ну да, там же нужно wildcard в референс пихать conan search openssl/* -r all: None found. эээ. а ну да, он же регистрозависимый conan search OpenSSL/* -r all: 9 found, hallelujah

Igor
25.10.2018
10:56:09
вот эта штука иногда здорово спасает https://02jandal.github.io/conan_inquiry/

Вот прямо сейчас сел ещё подолбаться с конаном, вы прямо экстрасенс)
ни, я просто вяло размышляю "надо сесть пилить доклад"

Google
Alex
25.10.2018
10:56:44
я прошёл эти квесты, но там дальше есть новые уровни :)

шикарно, спасибо за ссылку

Alex
25.10.2018
10:58:52
У нужной мне либы проблемы с зависимостями, не нашлось нужной ей версии zlib. Наверное, это просто недоделанный пакет, написал в bincrafters issue на Github

Alexander
25.10.2018
10:59:34
Konstantin

Konstantin
25.10.2018
11:00:12
Да, его сейчас делают

Vyacheslav
25.10.2018
11:21:17
Как только у вас начинаются shared_ptr у вас вылетает нормальное RAII, все обертывается на Maybe и вообще становится очень приятно программировать И вот эта возникающая maybe-обертка в COM как раз проблема COM, а не структуры, к которой его подсоединяют
"Начнём с того, что у COM нет проблем." -- проблемы могут появиться там, где его используют нарушая его правила. COM объект - это чисто shared_ptr модель, только счётчик ссылок не хранится инкапсулированно в отдельном участке динамической памяти, а хранится в самом объекте. Время жизни объекта определяется тем, как с ним работает клиент. Если клиент "отвалится", COM освободит ссылку на объект по таймауту. Подобная модель используется, например, в проброске C++ объектов в Lua, в C# и Java (Garbage Collector), в "правильном" TCP подключении, когда клиент закрывает подключение (по этикету звонящий вещает трубку первым). COM сам по себе ссылки на объект не удерживает, а проксирует работу клиента с ними на сервер. В примере "объект внутри диалога никогда не переживает диалог" этому объекту достаточно держать строгую ссылку на диалог, а диалогу - слабую на объект, если сам объект - это COM-объект. ИЛИ Диалогу достаточно держать строгую ссылку на объект, если диалог - это COM-объект. ИЛИ Если объект - это COM-объект, то он может увеличивать счетчик ссылок диалога при увеличении своего счетчика ссылок и уменьшать при уменьшении. В этом случае, если явно хочется позвать delete (или объявить объект членом класса диалога), то нужно переопределить реализацию Release, чтобы при достижении 0 объектным счетчиком ссылок, не звался delete this; В способах выше нет "полувалидных" объектов, но их нельзя явно убить по какому-то желанию/событию/самостоятельно. Нижний в иерархии объект должен быть выделен в динамической памяти или переживать старт-закрытие COM сервера. Убить явно такой объект - это всё равно что закрыть сервером клиентское подключение, позвать free для переданного в функцию указателя и т.п. #архитектура

Constantine
25.10.2018
11:23:01
"Начнём с того, что у COM нет проблем." -- проблемы могут появиться там, где его используют нарушая его правила. COM объект - это чисто shared_ptr модель, только счётчик ссылок не хранится инкапсулированно в отдельном участке динамической памяти, а хранится в самом объекте. Время жизни объекта определяется тем, как с ним работает клиент. Если клиент "отвалится", COM освободит ссылку на объект по таймауту. Подобная модель используется, например, в проброске C++ объектов в Lua, в C# и Java (Garbage Collector), в "правильном" TCP подключении, когда клиент закрывает подключение (по этикету звонящий вещает трубку первым). COM сам по себе ссылки на объект не удерживает, а проксирует работу клиента с ними на сервер. В примере "объект внутри диалога никогда не переживает диалог" этому объекту достаточно держать строгую ссылку на диалог, а диалогу - слабую на объект, если сам объект - это COM-объект. ИЛИ Диалогу достаточно держать строгую ссылку на объект, если диалог - это COM-объект. ИЛИ Если объект - это COM-объект, то он может увеличивать счетчик ссылок диалога при увеличении своего счетчика ссылок и уменьшать при уменьшении. В этом случае, если явно хочется позвать delete (или объявить объект членом класса диалога), то нужно переопределить реализацию Release, чтобы при достижении 0 объектным счетчиком ссылок, не звался delete this; В способах выше нет "полувалидных" объектов, но их нельзя явно убить по какому-то желанию/событию/самостоятельно. Нижний в иерархии объект должен быть выделен в динамической памяти или переживать старт-закрытие COM сервера. Убить явно такой объект - это всё равно что закрыть сервером клиентское подключение, позвать free для переданного в функцию указателя и т.п. #архитектура
Давайте обсуждать вопрос shared_ptr архитектуры безотносительно COM, OK? > В примере "объект внутри диалога никогда не переживает диалог" этому объекту достаточно держать строгую ссылку на диалог, а диалогу - слабую на объект Что должен сделать диалог, если weak в nullptr? > Диалогу достаточно держать строгую ссылку на объект Что должен делать объект, если диалога больше нет?

Vyacheslav
25.10.2018
11:25:50
Сейчас поясню.

Vyacheslav
25.10.2018
11:28:04
Собственно часть моего утверждения что shared_ptr система ошибочна в описании отношения диалога с его компонентами
shared_ptr система это надстройка над системой подсчета ссылок. Система подсчета ссылок применима всегда.

Constantine
25.10.2018
11:28:40
shared_ptr система это надстройка над системой подсчета ссылок. Система подсчета ссылок применима всегда.
система подсчета ссылок не описывает структуру отношения объекта и его поля (в смысле объектной модели С++)

вы меня понимаете? :)

Vyacheslav
25.10.2018
11:44:04
Условие: объект A не переживает объект B. Объект A создаётся в рамках жизни объекта B. Мы хотим передать ссылку на A во внешнюю среду. Решение в рамках shared_ptr: using namespace std; class B : enable_shared_from_this { public: class A { shared_ptr<B> strong_ref; A(const shared_ptr<B>& b) : strong_ref(b) {} } private: weak_ptr<A> _a; B() = default; public: static shared_ptr<B> CreateB() { return make_shared<B>(); } shared_ptr<A> GetA() { if (auto a = _a.lock()) return a; auto a = make_shared<A>(shared_from_this()); _a = a; return a; } } P.S. с телефона я пишу код долго.

Перепутал A и B в условии. Поправил.

Vyacheslav
25.10.2018
11:45:26
Его нельзя интерпретировать двояко

Constantine
25.10.2018
11:48:18
Его нельзя интерпретировать двояко
Если я ничего не путаю, ваш пример это optional поле класса, хранящее сильную ссылку на класс, правильно? Это как раз приводит к ситуации полумертвого объекта самого класса - в этом случае предполагается, что класс всегда находится в некотором полноценном состоянии и внешние факторы на это не влияют

Google
Constantine
25.10.2018
11:50:22
В какой момент в коде полумертвое состояние? "А" может конструироваться несколько раз, пока живёт В, но А В не переживает.
Да, это верно, это поле в смысле обязательности существования, но при этом нет внешних воздействий на время жизни объекта В

Это как раз модель что диалог не умер когда стек раскрутился до вызвавшего диалог

Constantine
25.10.2018
11:52:01
Да, т.к. время жизни В > времени жизни А.
Вот, эта модель означает, что В это не класс - ресурс по типу RAII Ну представьте что у вас в В файл открыт

Vyacheslav
25.10.2018
11:52:02
Это как раз модель что диалог не умер когда стек раскрутился до вызвавшего диалог
В этот момент можно залочиться, тогда диалог будет умирать после отпускания лока.

Например, через notify уведомлять о своём уничтожении.

Constantine
25.10.2018
11:53:03
Constantine
25.10.2018
11:54:55
Не вижу проблемы с открытым файлом.
Вот представьте, у вас В это таска, которая занимается отложенной записью каких-то данных на диск и держит блокировку на файл Вы передали её в поток-исполнитель, который её прибил (дропнул свою ссылку) по завершении, но на самом деле файл, возможно, остался открытым Правильно ли это?

Constantine
25.10.2018
11:57:36
Нет. Поток не может "прибить" её простым отпусканием shared_ptr. Он должен дождаться её явного разрушения, если это требуется.
Вот. Т.е. сверху появился теперь уже RAII-объект, выглядящий как В, но ожидающий смерти shared-версии B, правильно?

Vyacheslav
25.10.2018
11:57:47
Проблема держания кем-то ссылки на А, когда поток хочет дождаться уничтожения В -- не проблема классов А и В.

Constantine
25.10.2018
11:58:04
В момент завершения таски ссылок на А, конечно, быть не должно

Vyacheslav
25.10.2018
11:58:53
В момент завершения таски ссылок на А, конечно, быть не должно
В таком случае поток ожидать ничего не будет.

Constantine
25.10.2018
11:59:09
В таком случае поток ожидать ничего не будет.
Вопрос чего он ждет на самом деле

Google
Vyacheslav
25.10.2018
11:59:40
Вот. Т.е. сверху появился теперь уже RAII-объект, выглядящий как В, но ожидающий смерти shared-версии B, правильно?
Я не силён в терминологии RAII, но не считаю факт ожидания разрушения объекта ещё одним объектом.

Вопрос чего он ждет на самом деле
Если есть референсы на А, то их закрытия. В противном случае - ничего.

Constantine
25.10.2018
12:00:10
Я не силён в терминологии RAII, но не считаю факт ожидания разрушения объекта ещё одним объектом.
Давайте создадим объект SuperB который будет хранить shared_ptr<B> но в деструкторе ждать уникальности своей ссылки

Constantine
25.10.2018
12:00:44
Вот это типичный RAII класс

SuperB на самом деле это почти в точности В

Vyacheslav
25.10.2018
12:01:03
Можно ещё рекурсивным мьютексом эту штуку заменить

Constantine
25.10.2018
12:01:40
Можно ещё рекурсивным мьютексом эту штуку заменить
Независимо от характера ожидания это можно перенести в деструктор SuperB и создавать SuperB на стеке / хранить как нормальный объект

Constantine
25.10.2018
12:02:03
Для SuperB можно применять любой метод В

Вся разница логики лежит в одной крохотной части поведения

Vyacheslav
25.10.2018
12:03:32
Кстати, shared_ptr чем-то похож на такой SuperB. Также объект на стеке, но он не гарантирует освобождения объекта на который указывает.

Constantine
25.10.2018
12:03:55
И очень не похож одновременно. SuperB как раз класс типа RAII, это прямое управление владением

Vyacheslav
25.10.2018
12:04:38
Если требуется подчеркнуть, что в момент завершения такси В должен быть разрушен, то достаточно проверить факт его разрушения после отпускания shared_ptr. И если это не так, то кинуть исключение.

Vyacheslav
25.10.2018
12:05:20
Консенсус?

:)

Constantine
25.10.2018
12:05:48
Google
Constantine
25.10.2018
12:06:28
На самом деле все, что вы сделаете, когда напишете версию с assert это буквально то же самое, что написать struct B { A a; };

С точностью до того, что вы умеете рантайм-проверку делать

Vyacheslav
25.10.2018
12:07:07
Вот это требование что счетчик равен 1 и есть как раз то, о чем я говорил, когда говорил про отношение "быть полем"
Ну проверять я предлагаю через присвоение к weak_ptr, отпускание shared_ptr и проверку weak_ptr, поэтому про счётчик не понял.

Constantine
25.10.2018
12:07:34
Vyacheslav
25.10.2018
12:07:52
На самом деле все, что вы сделаете, когда напишете версию с assert это буквально то же самое, что написать struct B { A a; };
Да нет же. Как во внешнюю среду в таком случае правильно передать A&, время жизни которого также не контролируется RAII?

Таска же владеет В, так?

Constantine
25.10.2018
12:08:39
*На В
На самом деле на А. Вы попытались удалить В

Vyacheslav
25.10.2018
12:09:06
На самом деле на А. Вы попытались удалить В
Но проверяю я же то, что удалился В. :)

Не суть

Constantine
25.10.2018
12:09:26
Но проверяю я же то, что удалился В. :)
Теперь представьте что таска требует контекста от её инвокера

Vyacheslav
25.10.2018
12:10:00
Constantine
25.10.2018
12:10:14
Вот сейчас не понял. Какого контекста?
Ну т.е. инвокер отдает таске штуку, которая позволяет работать с инвокером

Например, класть ему новые таски в очередь

Vyacheslav
25.10.2018
12:10:46
А потом перейдём к новым условиям

Constantine
25.10.2018
12:12:16
Давайте вы сначала на вот этот вопрос ответите
Это вопрос о том, как правильно реализовывать логику полей - могу объяснить, но это немного букв

Внешнее поле создается, например, через обмен с using guard_ptr = std::unique_ptr<VirtuallyDestructible> который записывается в поле отдавшего класса

Т.е. A& a_ref(guard_ptr a_guard) { a_guard_ = std::move(a_guard); return a; }

Vyacheslav
25.10.2018
12:14:17
Это вопрос о том, как правильно реализовывать логику полей - могу объяснить, но это немного букв
Я утверждаю, что логика полей не отличается по сути от моей модели с одним лишним SuperB. Кроме того от такой struct B можно взять адрес &b.a и куда-то его сохранить или сохранить референс на b.a в оберточном объекте, который потом передать инвокеру через контекст

Страница 2468 из 2477