быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,695
|
||||||||||||||||||||||||||||||||||||||||||||||
При перекомпиляции сервера перекомпилируется клиент, а что, собственно в этом плохого?04.03.2013, 12:54. Показов 4126. Ответов 38
Метки нет Все метки)
(
Друзья!
Начинаем цикл вопросов про COM- Объекты. Первый вопрос возник по статье Безверхова, вот здесь статья. Вот там такой пример:
...Итак, компилим сервер:
Я ничё не понимаю. Может кто-то разъяснит мне, что имел ввиду Безверхов, говоря:
0
|
04.03.2013, 12:54 | |
Ответы с готовыми решениями:
38
Как отключить клиент от сервера, не закрывая при этом приложения
|
Модератор
![]() 3402 / 2173 / 353
Регистрация: 13.01.2012
Сообщений: 8,430
|
|
05.03.2013, 14:30 | |
то ли вы меня не поймете то ли я вас. если вы задаете вопрос о COM-объектах, то вы можете менять сервер как угодно - переставлять поля местами, менять их количество, позиции и сигнатуры методов - клиенту это без разницы до тех пор пока интерфейс не изменяется. вы ведь возвращаете клиенту интерфейс.
0
|
быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,695
|
|
05.03.2013, 16:28 [ТС] | |
в том-то и дело, что не о СOM! Понимаете, Безверхов начинает объяснение COM-объектов издалека с языка C++. Так что имеем ввиду, щас речь идёт о C++. То есть имеем чистой воды класс и main, они ещё и не COM-объекты и таковыми после компиляции и не будут, они просто разнесены по разным файлам-сырцам.
0
|
Модератор
![]() 3402 / 2173 / 353
Регистрация: 13.01.2012
Сообщений: 8,430
|
|
06.03.2013, 10:04 | |
1 если у нас обычный объект, то необходимость компиляции при внесении изменений в определение класса очевидна: изменение набора полей или обработчиков, их типов или сигнатур должно быть учтено на клиенте. в противном случае у него просто будет неактуальные адреса данных или точки входа, неверные размеры данных или процедуры передачи аргументов.
2 если у нас "обычный" объект который не содержит полей, а состоит из одних чистых виртуальных функций причем их набор и сигнатуры фиксированы, то как бы мы не издевались над его реализацией (над объектом наследником) компиляция клиента нам не нужна - мы всегда работаем с известным интерфейсом. это и есть COM.
1
|
быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,695
|
|
06.03.2013, 11:34 [ТС] | |
Ну, положим, первой части вполне хватило бы для ответа на вопрос, а вторая часть это то, чего не может быть
И там дальше в статье по-моему речь и идёт об этом. Не бывает хидера с таким описанием. (если, конечно мы ведём речь о C++ объектах. Ну то есть не выносим объект в отдельную dll). По-любому интерфейс наследника должен быть известен клиенту. Так что одним подключением абстрактного класса никак не обойтись. Ну, вы наверное имели ввиду, что если мы исхитримся сделать так, то это значит, что мы и сконструировали тот самый настоящий COM-объект, который находится в другом исполняемом модуле и никак иначе.
0
|
Модератор
![]() 3402 / 2173 / 353
Регистрация: 13.01.2012
Сообщений: 8,430
|
|
06.03.2013, 14:33 | |
чего не может быть? того что где-то живет нечто способное при вызове известной и неизменной функции вернуть указатель на объект класса содержащего одни чистые виртуальные функции (то есть интерфейс)? это вполне может быть. хоть в том же модуле хоть за его пределами. и это называется COM
0
|
Модератор
![]() 3402 / 2173 / 353
Регистрация: 13.01.2012
Сообщений: 8,430
|
|
07.03.2013, 08:22 | |
как раз сделать так что бы он был в одном исполняемом модуле человек может хоть на коленке. а вот сделать что бы он был в другом приложении - это заморочки с заглушками и маршаллингом. тоже конечно можно сделать свой педальный маршаллинг, но труд адов.
0
|
быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,695
|
||||||||||||||||||||||||||
10.03.2013, 03:23 [ТС] | ||||||||||||||||||||||||||
Внесём ясность в обсуждаемый вопрос. Мы выяснили, что при изменении хидера всегда надо пересобирать клиент.
Не по теме: Напоминаю, речь идёт исключительно о C++ коде, COM не трогаем. Я поторопился, задав вопрос в этом разделе- ну так значит не смог разобраться, пусть тему перенесут. Всегда ли? Эксперименты показали, что если клиент для доступа к данным будет пользоваться исключительно функциями-методами, тогда пересобирать его необязательно! Действительно, возьмём этот код, добавим в сервер функцию-метод (в хидер и в*.cpp)
__ZN5world8funktsiaEv из client.o ни с чем не перепутает __ZN5world8funktsiaEv из server.o Почему же линковщик может перепутать поля класса? На самом деле ответ прост, и он лежит на повержности. Все, кто отписался, его знают. А вот мне пришлось чуток подумать. В server.o генерируется код, который кладёт в первое поле world значение такое-то, а во второе такое-то. А в клиенте вынимаются значения из полей- из первого и второго. Если в хидере поменяются их имена, и клиент не узнает об этом на этапе компиляции, он не узнает этого никогда. Так и будет действовать, как запрограммирован при первой компиляции. Вернёмся с функциями, с ними всё проще. В коде они ведут себя как НЕ методы класса- то есть принадлежность к классу абсолютно никак не выявляется. (В объекте даже указателя на них нет. Был бы- не исключалась бы возможность путаницы, как с полями) Выясните размер world- он будет равен 8, по 4 байта накаждое поле string. Просто функция-метод (и конструктор) принимает указатель на объект класса и работает с ним. Все об этом знают, просто написать забыли. Ну вот и всё, собсно. То есть если пользуетесь для доступа к данным исключительно функциями, можете смело менять хидер и не трогать сырец с main. Всякое несоответствие (если таковое найдётся) между вызовами функций и тем, как они представлены в классе, выявится на этапе линковки. А не выявится, значит экзешник отработает корректно.
0
|
Модератор
![]() 3402 / 2173 / 353
Регистрация: 13.01.2012
Сообщений: 8,430
|
|
11.03.2013, 11:34 | |
итак, делаем игрушечный интерфейс и игрушечную библиотеку COM.
имеем заголовочный файл в котором есть: - определение класса my_iface с чистыми виртуальными функциями f1 и f2 - это наш игрушечный интерфейс - прототип функции create_obj возвращающей указатель на объект класса my_iface - это наша игрушечная библиотека COM (наш аналог функции CoCreateInstance). собираем DLL в которой есть класс реализующий интерфейс и есть функция возвращающая указатель на реализацию. подключаем DLL к проекту. если в заголовочном файле в определении класса поменять местами виртуальные функции f1 и f2, то при вызове obj->f1() мы ничуть не удивившись обнаружим на экране информацию говорящую о том, что реально была вызвана функция f2.
1
|
11.03.2013, 11:45 | |
0
|
11.03.2013, 11:54 | |
Не по теме: Неумение пользоваться имеющимися классами (в частности попытки наследоваться от тех классов, которые для этого не предназначены) вовсе не значит, что класс написан неправильно. Возьмите хотя бы std::string. В шарпике есть например sealed, четко говорящий о том, что наследование запрещено. В плюсах же приходится немного углубляться в документацию.
0
|
11.03.2013, 12:07 | |
Не по теме: безусловно все из-за него, родимого. никто не говорил "неправильно". говорил "ненормально" в плане отсутствия у проектировщика класса желания исключить потенциальную возможность утечки памяти или ошибки доступа. в любом случае данная дискуссия не относится к вопросу, имеет черты религиозной и на мой взгляд продолжать ее в данной теме нежелательно.
1
|
быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,695
|
|
11.03.2013, 12:59 [ТС] | |
Угу, только я разделил для себя:
1)использование абстрактного класса это одна история- ваш пример, 2)неиспользование абстрактного класса- другая история. Сейчас мы говорим о втором примере. Никаких абстрактных классов! Мне почему-то казалось это очевидным, раз не оговорено обратное ![]() Что касается вашего примера, то я вчера долго думал над ним и пришёл к тому же выводу, что и вы. Создал даже тему в разделе C++ потому, что к COM это пока никаким боком. Я и эту-то поторопился в этом разделе создавать. Программа взаимодействует с классом исключительно через интерфейс. Однажды класс меняется и меняется его хидер. Надо ли перекомпилировать всю программ вот оттуда моя цитата:
0
|
быдлокодер
![]() 1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,695
|
|
11.03.2013, 13:16 [ТС] | |
Вопрос "что внутри" это следствие вопроса "надо ли перекомпилировать", а так всё, никакого больше.
0
|
11.03.2013, 13:16 | |
Помогаю со студенческими работами здесь
39
Проверка на стороне сервера, что клиент обработал отправленные данные Зависает клиент при приёме от сервера
Чем пользоваться при создании клиент-сервера? Тормоза При Перекомпиляции Бд Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Опции темы | |
|
Новые блоги и статьи
![]() |
||||
MVC фреймворк в PHP
Jason-Webb 19.04.2025
Архитектурный паттерн Model-View-Controller (MVC) – это не просто модный термин из мира веб-разработки. Для PHP-программистов это фундаментальный подход к организации кода, который радикально меняет. . .
|
Dictionary Comprehensions в Python
py-thonny 19.04.2025
Python славится своей выразительностью и лаконичностью, что позволяет писать чистый и понятный код. Среди множества синтаксических конструкций языка особое место занимают словарные включения. . .
|
Шаблоны и протоколы для создания устойчивых микросервисов
ArchitectMsa 19.04.2025
Микросервисы — архитектурный подход, разбивающий сложные приложения на небольшие, независимые компоненты. Вместо монолитного гиганта, система превращается в созвездие небольших взаимодействующих. . .
|
Изменяемые и неизменяемые типы в Python
py-thonny 19.04.2025
Python славится своей гибкостью и интуитивной понятностью, а одна из главных его особенностей — это система типов данных. В этом языке все, включая числа, строки, функции и даже классы, является. . .
|
Интеграция Hangfire с RabbitMQ в проектах C#.NET
stackOverflow 18.04.2025
Разработка современных . NET-приложений часто требует выполнения задач "за кулисами". Это может быть отправка email-уведомлений, генерация отчётов, обработка загруженных файлов или синхронизация. . .
|
Построение эффективных запросов в микросервисной архитектуре: Стратегии и практики
ArchitectMsa 18.04.2025
Микросервисная архитектура принесла с собой много преимуществ — возможность независимого масштабирования сервисов, технологическую гибкость и четкое разграничение ответственности. Но как часто бывает. . .
|
Префабы в Unity: Использование, хранение, управление
GameUnited 18.04.2025
Префабы — один из краеугольных элементов разработки игр в Unity, представляющий собой шаблоны объектов, которые можно многократно использовать в различных сценах. Они позволяют создавать составные. . .
|
RabbitMQ как шина данных в интеграционных решениях на C# (с MassTransit)
stackOverflow 18.04.2025
Современный бизнес опирается на множество специализированных программных систем, каждая из которых заточена под решение конкретных задач. CRM управляет отношениями с клиентами, ERP контролирует. . .
|
Типы в TypeScript
run.dev 18.04.2025
TypeScript представляет собой мощное расширение JavaScript, которое добавляет статическую типизацию в этот динамический язык. В JavaScript, где переменная может свободно менять тип в процессе. . .
|
Погружение в Kafka: Концепции и примеры на C# с ASP.NET Core
stackOverflow 18.04.2025
Apache Kafka изменила подход к обработке данных в распределенных системах. Эта платформа потоковой передачи данных выходит далеко за рамки обычной шины сообщений, предлагая мощные возможности,. . .
|