Переключение на Главную Страницу Страницы: [1] 2 3  ОтправитьПечать
Очень популярная тема (более 25 ответов) Say "good bye" to CMyContextBase (число прочтений - 12974 )
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Say "good bye" to CMyContextBase
08. Августа 2007 :: 02:22
Печать  
Проблемы CMyContextBase.

Макросы. Не признают пространства имен, разворачиваются иногда в совершенно неожиданные конструкции, в случае ошибок компилятором выдаются крайне мало понятные сообщения. Как завещал нам Страуструп, "препроцессор C должен быть уничтожен".

Неудобная регистрация методов. Нужно указывать количество параметров вручную. Если меняется метод, надо не забыть поменять его описание в BEGIN_BL_METH_MAP. Это не удобно и чревато ошибками.

Неудобно программировать контекстный класс. Необходимо вручную разбирать массив параметров CValue и вручную преобразовывать параметры в нужные типы для текущего метода. В декларации класса не видно сколько параметров принимает каждый метод и каких типов. Всегда это CValue. Очень не удобно и очень не наглядно.

Необходимость создания мусорных функций для определения параметров по умолчанию. Эти функции не имеют отношения к функционированию класса, они чисто утилитарны, но должны присутствовать в определении класса наравне с методами, реализующими основной функционал класса. Также необходимо в этих функциях каждый раз реализовывать switch...case, что неудобно и чревато ошибками.

Необходимость наследовать класс от CMyContextBase. При проектировании классов следует выбирать наименее сильную связь между классами. Наследование - наоборот самая сильная связь. В реализации контекстной обертки нет никакой необходимости в наследовании - достаточно простого делегирования. Более того наследование сильно уменьшает гибкость решения: класс привязан к CMyContextBase и к MFC. Если нет возможности модифицировать основной класс, то приходится создавать мусорный класс-обертку.

Крайне не удачно реализована регистрация контекстных классов. Использовано MS-специфичное, непереносимое на другие платформы, решение. Зачем так было сделано - не ясно. Стандартных средств языка C++ более чем достаточно для решения задачи. Кроме того, регистрация контекстных классов поставлено в зависимость от стартап кода компоненты. Это без всякой необходимости увеличивает связность между различными модулями компоненты. Регистрация может происходить самостоятельно, для каждого контекстного класса отдельно.
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #1 - 08. Августа 2007 :: 02:23
Печать  
Предлагается более удачное решение.

Исходники находятся здесь: http://yoksel.cvs.sourceforge.net/yoksel/SpreadSheet/Utils1s/Context/
Тесты к ним находятся здесь: http://yoksel.cvs.sourceforge.net/yoksel/SpreadSheet/Tests/Utils1s/Context/
Памятка по использованию находится здесь: http://yoksel.sourceforge.net/?wakka=PamjatkaPoUtils1sContext&v=9aq
Для демонстрации использования решения создана ВК Michele - позволяет рисовать в окне 1С методами GDI и сохранять созданное изображение в файл формата BMP, JPG или PNG. ВК находится здесь: http://uzhast.fatal.ru/Michele/

Краткое описание решения.

Оберточные классы представляют собой шаблоны C++. Никаких макросов для реализации использовано не было. Справедливости ради можно отметить, что сообщения компилятора при использовании шаблонов в случае ошибок так же не блещут понятностью, как и при использовании макросов. Однако шаблоны не могут выйти из своего пространства имен, ведут себя более предсказуемо, место ошибки показывается гораздо точнее.

Решение позволяет строит переходники почти к любому произвольному классу C++. Будем называть такие классы основными. Основной класс может вообще не знать о существовании 1С, типов CValue и CBLContext. Мы просто указываем компилятору, чтобы он сгенерил переходник к основному классу и указываем к каким методам и свойствам следует создать обертки. Мы просто указываем RegisterMethod ("РусИмя", "EngName", MainClass::Method). Далее мы можем менять количество параметров у метода, менять типы параметров и возвращаемое значение. Определение контекста при этом менять не нужно. Достаточно перекомпилировать проект и компилятор автоматически создаст метод-обертку, для измененного метода основного класса.

Если метод использует параметры по умолчанию, то их мы также описываем при вызове RegisterMethod. При этом мы используем реальные типы (число, строка и т.д.) - работать с CValue не нужно. Также нет никакой необходимости в мусорных функциях, сообщающих 1С о параметрах по умолчанию - весь этот мусор будет сгенерирован автоматически.

Контекстный класс-обертка не связан отношениями наследования с основным классом. Он может единолично владеть объектом основного класса, разделять владение с другими объектами или может быть просто подключен к существующему объекту основного класса.

Регистрация контекстных классов происходит полностью автоматически и децентрализовано. Нет никаких зависимостей от стартап кода.

Плюсы решения.

Можно создавать контексты для уже существующих классов C++. Например, см. в Michele реализацию Michele::CFont и Michele::CBrush - это автоматические обертки над MFC-шными CFont и CBrush.

Основной класс не связан с 1С и ее заморочками. Он не знает про CValue. Он работает со своими родными типами. Это увеличивает возможность повторного использования решения. Например, для основного класса можно сделать переходник не для CBLContext, а для ILanguageExtender, что позволит использовать этот класс не только в 7.7, но и в 8.х. Или можно сделать переходник для IDispatch, что позволит работать с классом по OLE-automation.

Написание контекстных классов становится удовольствием. Их можно создавать быстро и работать с ними становится удобно. В определении класса видны его реальные параметры и возвращаемое значение.

Классы удобно использовать из C++. В несколько раз упрощается тестирование этих классов.

Недостаток: решение невозможно использовать с компилятором VC6. Необходимо использовать более современный компилятор - Intel C++.
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #2 - 08. Августа 2007 :: 12:47
Печать  
Все это хорошо.
Но подскажи, где взять компилятор ИнтелС++ ?
лучше прямой линк Улыбка
Хочется посмотреть и проанилизировать Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Say "good bye" to CMyContextBase
Ответ #3 - 08. Августа 2007 :: 17:04
Печать  
Круто!

Я тоже в итоге пришел к мысли, что надо отделять интерфейсный функционал;
т.е. класс-наследник от CMyContextBase - это просто интерфейсная пустышка, агрегирующая основной функционал.

Кстати, эта идея разделения в 1cpp блестяще была продемонстрирована Дмитром в ТП.
Конечно, на базе VC6 это все решает только один минус, но зато самый главный (отсутствие мусора, прозрачность параметров, повторное использование).

Интересно будет посмотреть на твою реализацию через шаблоны, когда uzhast.fatal.ru заработает.

P.S.
Курилка рулит!! Улыбка
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #4 - 08. Августа 2007 :: 22:21
Печать  
artbear писал(а) 08. Августа 2007 :: 12:47:
Все это хорошо.
Но подскажи, где взять компилятор ИнтелС++ ?
лучше прямой линк Улыбка

Можно начать отсюда: http://www.intel.com/cd/software/products/asmo-na/eng/compilers/279578.htm
У них уже, кстати, 10-я версия вышла Улыбка
Прямой ссылки, к сожалению не сохранилось - давно скачивал.

kms писал(а) 08. Августа 2007 :: 17:04:
Я тоже в итоге пришел к мысли, что надо отделять интерфейсный функционал;
т.е. класс-наследник от CMyContextBase - это просто интерфейсная пустышка, агрегирующая основной функционал.

Кстати, эта идея разделения в 1cpp блестяще была продемонстрирована Дмитром в ТП.

Скорее, не "блестяще продемонстрирована", а "выбрана из безысходности" Улыбка Когда каким-то классом становится сложно пользоваться из-за трудностей в разработке и/или отладке, то этот класс всегда стараются сделать максимально легким, а основную логику вынести в другие классы. Так что, то, что подобный подход использует прародитель CMyContextBase, говорит в пользу отказа от этого класса Подмигивание

kms писал(а) 08. Августа 2007 :: 17:04:
Конечно, на базе VC6 это все решает только один минус, но зато самый главный (отсутствие мусора, прозрачность параметров, повторное использование).

От VC6 лучше вообще отказаться. Кроме скорости компиляции вообще нет никаких достоинств - одни проблемы. Плюс кривая стандартная библиотека. Ужас короче. А вот Intel - вещь замечательная по всем параметрам. Они там умудряются корректно поддерживать все студии (VS6, VS2003, VS2005) - корректно комилируется код заголовков любой студии + на уровне объектников полностью совместим с MS link'ом. А вот стандартный компилятор в VS2005 от заголовков VS6 шизеет по страшному.

kms писал(а) 08. Августа 2007 :: 17:04:
Интересно будет посмотреть на твою реализацию через шаблоны, когда uzhast.fatal.ru заработает.

Отзеркалился на http://uzhast.fromru.su/Michele/
Там, правда, файлы скачиваются со скоростью 4Кб/с (гады...), но у меня там файлы не слишком здоровые.
  
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #5 - 09. Августа 2007 :: 04:11
Печать  
Uzhast писал(а) 08. Августа 2007 :: 22:21:
artbear писал(а) 08. Августа 2007 :: 12:47:
Все это хорошо.
Но подскажи, где взять компилятор ИнтелС++ ?
лучше прямой линк Улыбка

Можно начать отсюда: http://www.intel.com/cd/software/products/asmo-na/eng/compilers/279578.htm
У них уже, кстати, 10-я версия вышла Улыбка
Прямой ссылки, к сожалению не сохранилось - давно скачивал.

Там вроде только эвалюшная версия на 30 дней свободно скачиваемая.
Толку от этих 30 дней... ((
А у VTune размеры запредельные...
  
Наверх
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #6 - 09. Августа 2007 :: 04:21
Печать  
trdm писал(а) 09. Августа 2007 :: 04:11:
Там вроде только эвалюшная версия на 30 дней свободно скачиваемая.
Толку от этих 30 дней... ((
А у VTune размеры запредельные...

Там полная версия, к которой можно получить у Intel лицензию, действующую 30 дней. В свое время мне было лень получать лицензию у Интел и я скачал из Сети первую попавшуюся. К сожалению, она оказалась дефектная. Из-за нее компилятор заглючил и ограничение на 30 дней перестало работать.
  
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #7 - 09. Августа 2007 :: 04:36
Печать  
Один черт 30 дней. Ты сам знаешь как оно бывает.
сегодня скачал, завтра наполучал заданий и вынырнул как каз на 31-й день, так и не посчупав и не ощутив...
  
Наверх
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #8 - 09. Августа 2007 :: 04:39
Печать  
trdm писал(а) 09. Августа 2007 :: 04:36:
Один черт 30 дней. Ты сам знаешь как оно бывает.
сегодня скачал, завтра наполучал заданий и вынырнул как каз на 31-й день, так и не посчупав и не ощутив...

Говорю же, есть дефектные лицензии, без ограничения срока действия Улыбка
  
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: Say "good bye" to CMyContextBase
Ответ #9 - 09. Августа 2007 :: 05:11
Печать  
Я так понял, что больше 10 аргументов у метода не реализовано?
И таки не понял, как задать, что такой-то параметр можно опускать.
Можно махонький примерчик?

ЗЫ. Сам то я давно уже CMyContextBase не юзаю, не нравится мне уже свое детище.
  
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: Say "good bye" to CMyContextBase
Ответ #10 - 09. Августа 2007 :: 05:27
Печать  
Пара замечаний
в Utils1s.Context.CContextImpl ::GetParamDefValue параметр pDefValue может приходить NULL.
Это когда объект этого контекста назначен контекстом для CBLModule, и выполняется его компиляция, и компилятор просто проверяет, можно ли опускать этот параметр.

И Michele::Context::TypeTraits<CPoint>::FromCValue,
dynamic_cast<CContext<Michele::Context::CPoint> *> (Value1s.GetContext ())
Если контекстом придет объект, реализованный в дллке, собранной  без RTTI, то упадет все нахрен.

А так ниче, внушает...
Надо пару идей взять себе на вооружение...
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #11 - 09. Августа 2007 :: 05:29
Печать  
orefkov писал(а) 09. Августа 2007 :: 05:11:
Я так понял, что больше 10 аргументов у метода не реализовано?

Ага.
orefkov писал(а) 09. Августа 2007 :: 05:11:
И таки не понял, как задать, что такой-то параметр можно опускать.
Можно махонький примерчик?

Во-первых, можно использовать указатели. В этом случае пользователю контекста разрешено опускать параметры, а основному классу будет передаваться NULL.

Во-вторых, есть две версии функции RegisterMethod:
1) Принимает три параметра: имена метода и адрес метода. (нет дефолтных параметров).
2) Количество параметров 3 + N, где N - количество параметров у метода. Первые 3 - как у предыдущего. Остальные - дефолтные параметры. Дефолтный параметр может принимать:
а) собственно дефолтное значение (int, std::string и т.д.)
б) значение DefArgHandling::MustBeDefined - это означает отсутствие дефолтного значения.

Пример кода.
Допустим есть объект CPen с методом void CreatePen (int Style, int Width, COLORREF Color). Мы хотим, чтобы юзверь мог опустить параметр Width и в этом случае было бы подставлено значение 1. В InitContext пишем:
Код
Выбрать все
ThisContext::RegisterMethod ("CreatePen", "CreatePen",
	ThisClass::CreatePen,
	DefArgHandling::MustBeDefined, // обязательный
	1, // по умолчанию - 1
	DefArgHandling::MustBeDefined // обязательный
);
 



orefkov писал(а) 09. Августа 2007 :: 05:11:
ЗЫ. Сам то я давно уже CMyContextBase не юзаю, не нравится мне уже свое детище.

А, так это ты автор Улыбка А мне почему-то казалось, что Dmitro Улыбка Извиняюсь. (копирайтов в mycontextbase.* нету Печаль)
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #12 - 09. Августа 2007 :: 05:36
Печать  
orefkov писал(а) 09. Августа 2007 :: 05:11:
ЗЫ. Сам то я давно уже CMyContextBase не юзаю, не нравится мне уже свое детище.

А что юзаешь вместо? Можешь дать пощупать? Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: Say "good bye" to CMyContextBase
Ответ #13 - 09. Августа 2007 :: 05:37
Печать  
Uzhast писал(а) 09. Августа 2007 :: 05:29:
А, так это ты автор Улыбка А мне почему-то казалось, что Dmitro Улыбка Извиняюсь. (копирайтов в mycontextbase.* нету Печаль)

Это наше совместное детище. Можно сказать, я родитель, а Dmitro воспитатель Улыбка
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Say "good bye" to CMyContextBase
Ответ #14 - 09. Августа 2007 :: 05:37
Печать  
А неопределенное количество параметров, как я понял, не поддерживается?
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 3 
ОтправитьПечать