Отговори на тема  [ 32 мнения ]  Отиди на страница Предишна  1, 2, 3  Следваща
C++ и микроконтролери ? 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Тука паралелно тръгнаха няколко нишки в дискусията... :)
Аз ще карам по моята нишка само.
Значи ето един пример от мене:
Код:
class CViewBaseItem
{
protected:
    const uint8             m_cXpos;
    const uint8             m_cYpos;
    const int8* const       m_pLabel;

    uint8 GetLabelLength(void) const;

public:

... //Тука съм спестил малко декларации на методи

    CViewBaseItem(const uint8 xpos, const uint8 ypos, const int8 * const p_label)
    :   m_cXpos(xpos),
        m_cYpos(ypos),
        m_pLabel(p_label)
    {}
    ~CViewBaseItem(){}
};

Това е базов клас.
Към конструктора има инициализационен списък след ":" и преди първата къдрава скоба. В случая конструктора ми е инлайн за да се излъже компилатора да не генерира код за празната функция.
Ето и един клас който наследява базовия:
Код:
class CViewItemValOffset : public CViewBaseItem
{
protected:
    const CItemBaseValue* const   m_pValue;
    const uint8   m_cValueOffset;

public:
    ... // декларации на методи

    CViewItemValOffset(const uint8 xpos, const uint8 ypos, const int8 * const p_label, const CItemBaseValue* const p_val, const uint8 val_offset)
    :    CViewBaseItem(xpos,ypos,p_label),
        m_pValue(p_val),
        m_cValueOffset(val_offset)
    {}
    ~CViewItemValOffset(){}
};

Тук също имам инициализационен списък в който подавам и параметри на конструктора на базовия клас.
Ето дефиниция на един обект:
Код:
const CViewItemValOffset     g_CylSensorSerialNum
(
    EDITCALDATA_VIEW_ITEM_XPOS,         // xpos
    3,                                  // ypos
    "Serial No",                        // p_label
    &g_CylSensorSerialNumValue,         // p_val
    EDITCALDATA_VIEW_VAL_OFFSET         // val_offset
);

Всичко това отива в ROM-а защото обекта ми е обявен като const и е в глобъл скопа.
Това имах впредвид.
Не знам по каква причина искаш да използваш struct вместо class. Но в някои случаи то е същото.
С++ ти дава възможност в инициализационния списък на конструктора да направиш къмпайл тайм инициализация. В същото време в тялото на конструктора може да имаш и рън тайм инициализация.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Пет Фев 26, 2010 12:19 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Донякъде успях... но се получава манджа с грозде :-(

Най-малкият проблем е, че писането на конструктури доста увеличава кода. Декларацията става двойно и тройно по-голяма - веднъж декларирам полетата, втори път ги изброявам в конструктора и трети път в списъка след него. Допълнително трябва да слагам typedef, щото един тип от сорта на указател на функция е прекалено тежък за да го преписвам 3 пъти...

Но големият проблем е, че наследяването и шаблонирането се бият взаимно.... или аз нещо не мога да го измисля като хората ;-)

Значи целите ми са две:

1) Базовият клас/структура да има полета по-точно указатели от неопределен тип. Примерно всеки драйвер си има указател към хардуерните регистри на съответната периферия. Затова базовия клас е шаблон, на който подавам като параметри типа на указателите. Така като дефинирам драйвер той си е с правилните типове и няма нужда от тайпкаст.

2) Всеки драйвер да може да си добавя допълнителни полета според нуждите... За това искам да ползвам наследяване.


Поотделно и шаблонирането и наследяването работят. Но съчетая ли ги двете получавам боза....Мъчих няколко варианта, но все зациклям... Примерно най-видим е случая когато в басовия клас имам указател към себе си, или пък указателя се ползва като параметър на функция. Реално типът трябва да е като на наследника, но пък е деклариран в базовия клас и зациклям или в декларации, или в инициализации. В най-добрия случай се налагат един луди тайпкастове, ама това обезсмисля идеята за шаблоните... Демек слагам шаблони уж да махна тайпкостове, а пък в крайна сметка се налгат други и то много по-шибани тайпкастове...
Може би трябва да разкарам функциите и да ги направя виртуални методи, тогава "this" не се подава, не се декларира и не се налага да се тайпкаства. Но първо както казах искам да избегна бачкане с виртуалните таблици от асемблер, пък и 'this' не изчерпва всички проблеми....

Търся някакво чисто решение, не защото съм чак такъв педант... Просто имам код в който яко се ползват структури - десетки типове, някои вложени една в друга, други навързани с указатели... Луда работа...


Пет Фев 26, 2010 2:26 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Мдаа познат лабиринт :D
Мисля че нормалния начин е да използваш виртуални методи. Не че няма и други начини де. :)
Ако запазиш и структурите указатели към функции само заради асемблерския код, дали няма да успееш да накараш компилатора да ги инициализира(compile time) за всеки обект с адресите на съответните виртуални методи... Т.е. ще имаш дублиране на част от виртуалната таблица в твоята структура.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Пет Фев 26, 2010 3:38 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Май намерих изход от лабиринта ;-)

Идеята е базовия клас да го декларирам като шаблон, в който всички "спорни" типове се подават като параметри на шаблона. Дотук няма проблем, защото това е просто с шаблон с някакви типове...

После декларирам едновременно наследник на класа и попълвам шаблона. Трикът е че подавам новополучения тип като параметър.

Изглежда мааалко объркващо на пръв поглед ;-) Декларирам клас, който наследява шаблон, който пък ползва наследения тип дето декларирам в момента... Малко като омагьосан кръг, но минава ;-)

Ето как изглежда принципно:

Код:
//base class
template<typename FUTURE_TYPE>
struct BASE_CLASS_TEMPLATE
{
   const FUTURE_TYPE   * this_ptr;
    BASE_CLASS_TEMPLATE(
          const FUTURE_TYPE   * param
         )
      :this_ptr(param) {}
};


//derived class
struct DERIVED_CLASS: BASE_CLASS_TEMPLATE<DERIVED_CLASS>
{
   //noting but constructor
   DERIVED_CLASS(
         const DERIVED_CLASS   * param
         )
      :BASE_CLASS_TEMPLATE<DERIVED_CLASS>(param) {}
};

const DERIVED_CLASS object(&object);


Накрая съвсем в "духа на концепцията" създавам обект, като го инициализирам със собствения му адрес ;-)


Естествено, че примера е уникално безсмислен... но Zdrav мисля че ще ме разбере колко голям е смисъла му (втори ден го боря) ;-)


Пет Фев 26, 2010 3:56 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Ами няма пълно щастие :x


както се оказа че няма const class... това е бъг на GCC от 2006 г. и едва ли ще го оправят скоро :evil:


тъй че Zdrav твоите обекти ще са в ROM само ако не ползваш GCC...


Пет Фев 26, 2010 11:05 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Ааа не, точно GCC ползвам :D
От един час чета твоите усуканици тука и се опитвам да разбера за кой дявол ги правиш.
Наистина уникална безмислица... :D :D :D детето дава типа на бащата :?
Каква е целта? Да използваш в базовия клас указатели към типове които още не си декларирал, като избегнеш виртуалните методи?
Всъщност това не е дискусия за петък вечер :)

_________________
Най-опасният враг на истината и свободата е мнозинството.


Пет Фев 26, 2010 11:38 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Zdrav написа:
Ааа не, точно GCC ползвам :D


Значи не си забелязал, че const class го разполага в .bss секция демек в RAM... A на теория трябва да е в .rodata

Изръчках и нета и всичко... Пише че е бъг и толкоз.


Цитат:
От един час чета твоите усуканици тука и се опитвам да разбера за кой дявол ги правиш.
Наистина уникална безмислица... :D :D :D детето дава типа на бащата :?
Каква е целта? Да използваш в базовия клас указатели към типове които още не си декларирал, като избегнеш виртуалните методи?


Целта е да избегна тайпкастването... Всъщност досега е с тайпкастване, но е досадна работа. Нито като пиша мога да ползвам код асистант, нито като дебъгвам мога да си ги виждам удобно структурите, а за евентуални грешни кастове да не говорим.
Примерно драйверите - един драйвер ми е 2 структури + 3 функции. И ми е важно типовете в тия структури да са с правилен тип, както и параметрите на функциите да са с правилен тип.Ако не са, трябва да каствам като поп...

С горния пример "бащата и детето" се постига целта - типовече са правилни... Лошото е, че няма const... а и слага едни грозни конструктори...
Вариантът истински клас с виртуални методи е по-кофти решение в случая. Той решава проблема само с 'this" докато "бащата и детето" оправя проблемите с всички типове.
Освен това виртуалните методи се викат през виртуална таблица (става по-бавно) и не е добре да се викат от асемблер (каквото ми е намерението)...

Има още един вариант - всеки драйвер да си декларира собствени структури и да няма наследяване от базов тип. Без наследяване няма да имам класове а PODS (Plain old data structures) и няма да имам проблем с const... Ще остане само риска от неправилно подредена структура, но това ще се хваща бързо ;-)


Съб Фев 27, 2010 12:48 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Прав си Миро :)
Сега направих един objdump и... да, въпросния const обект от примера, който дадох, отива в .bss ??? :?
Нещо не се вързва. Но е така.
А за излизането от лабиринта мисля трябва да се гледа на С++ не като възможности които дава, като тази да си увиеш сам крака около врата, ами трябва абстрактния модел да описва адекватно реалния обект. За това и в началото споменах, че важна е целта, да си наясно с нея и да не я загубиш в лабиринта от похвати и възможности които С++ или по-точно С++ компилатора ти дава.
Такива усукани неща аз лично установих, че е по-добре да избягвам. По-добър е консервативния подход. На няколко пъти при излизане на нова версия на arm-elf-gcc ми изскачаха разни проблемчета или уорнинги(предупреждения де :). Т.е. в GCC често бутат и правят реорганизации. Ако една засукана хватка минава със сегашната версия на компилатора със следващата може да има проблеми.
А за виртуалната таблица по-горе се опитах да ти предложа да поддържаш в твоята структура копие на необходимите адреси на виртуалните методи, както досегашните ти указатели към функции. Инициализираш ги в конструктора и асемблера си ги ползва както досега. Ще имаш дублиране но е вариант за удовлетворяване на противоречивите изисквания.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Съб Фев 27, 2010 3:08 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Zdrav написа:
А за виртуалната таблица по-горе се опитах да ти предложа да поддържаш в твоята структура копие на необходимите адреси на виртуалните методи, както досегашните ти указатели към функции. Инициализираш ги в конструктора и асемблера си ги ползва както досега. Ще имаш дублиране но е вариант за удовлетворяване на противоречивите изисквания.


Може и да не те разбирам добре, но не виждам смисъл... Целта е указателите да са в базовия клас, което поставя въпроса от какъв тип ще те? Пък и много объркващо става - указател към виртуален метод...
Както и да е... концепцията с "баща-дете" на 100% решава проблема с типовете и с virtual само ще дублирам същите указатели и във виртуалната таблица. А тая таблица няма да се използва изобщо, защото "методите" на драйверите се викат само и единствено от кърнела на асемблер.


Цитат:
За това и в началото споменах, че важна е целта, да си наясно с нея и да не я загубиш в лабиринта от похвати и възможности които С++ или по-точно С++ компилатора ти дава.


Ами то се вижда че съм объркан доста ;-)
Търся, но не знам какво... Ама нали затова е тоя форум, аз ако знаех какво търсех досега да съм го намерил в гугъл ;-) В тоя ред на мисли, който измисли търсачка дето бачка с интуиция ще направи революция :D


Просто не знаех и още на знам какво да очаквам от минаването на С++. Ех, не чак толкоз де... имам доста опит и ООП, включително и с С++, но на РС а там нещата стоят малко по-различно...
Предполагам не само аз, ами и много други от тоя форум работим с множество езици... От асемблери, Ц-та и стигнем до неалгоритмични неща от сорта на VHDL. Последно няколко месеца бачках на PHP, който между другото е доста приятен и лек за бачкане ;-)
Та мисълта ми беше, че покрай толкоз много бози моят начин на оцеляване е като си изработват нещо като "стил" за всеки един език и после го мултиплицирам многократно. Просто гледам да използвам едни и същи похвати, но за целта те трябва да са универсални.
Ако вместо структури ще използвам класове, то е защото се предполага че така нещата стават по-добре. Но ако класовете ме ограничават с проблеми като const и се окаже че всъщност резултата е по-кофти от използването на структури. На практика само ще съм си загубил времето...
Не знам как да го кажа - търся прогрес, по-добър език, който да ми намали проблемите, а не да ми замени едни проблеми с други...

Тъй де, явно ще ползвам само ограничен набор от ++ нещата и към тоя момент проблемът ми е да си изясня какво точно мога да ползвам, без това да ми създаде главоболия. Примерно драйверите - то е ясно, че мога да ги направя истински класове с виртуални методи и прочие. Само че в случая става дума за ембедед приложение, където всеки байт RAM е важен, затова в сегашния ми модел съм разделил драйвера в две структури - едната e info и съдържа всички параметри на драйвера, а другата е data демек там слагам RAM променливите. Само че като мина към клас-концепцията всичко се разполага в .bss. Така се губи смисъла да има две структури. Като добавим и грозните конструктури се получава че едновременно губя RAM, губя ROM от конструкторите, става по-тромаво заради калпаво написаните конструктори... И всичко това за да избегна тайпкастване. Май не си струва ;-)

Сякаш има нещо сбъркано в С++. То е нещо като нищо.... От една страна в Ц-то заради стриктните типове се работи трудно. От друга страна са не-стриктните езици и скриптове - примерно PHP, където работата е песен. Примерно на PHP с половин страничка код отварям сокет, изчитам един куп данни, парсвам ги и генерирам други данни. На Ц подобни нещо ще изяде 10-на страници код, докато уточня типовете, докато направя декларации, дефиниции и... ще се мръкне ;-)
На теория Ц++ трябва да вземе предимствата от двата подхода - леката работа без типосване и бързината на Ц-то. Но на практика май взема недостатъците - тромавостта на скриптовете и трудността на Ц :D

Както и да е... тия философски размисли не ми помагат, сега сядам да умувам как да си направя нещата на структури ли, на класове ли... Да не взема и аз само недостъците на двете ;-)


Съб Фев 27, 2010 5:59 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 17, 2005 5:07 pm
Мнения: 813
Местоположение: Сливен
Мнение 
И аз да вляза малко във философските размисли .... знаеш ли кой е езика който свързва двата езика и прави кода читаем и прост.....
C# :))
Верно тук вече говорим за високо ниво ООП ама .... и аз ползвам поне 5 езика ама честно казано за PC като че ли C# най ми впасва и ми решава задачите с минимум редове код . :oops:


Съб Фев 27, 2010 8:15 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Аз и за РС не бих го ползвал, ама това е друга бира ;-)

За контролери изборът ми се свежда до С/C++ за съжаление... Казвам за съжаление, защото в моя случай ми трябва и функционалност на високо ниво демек ала-скрипт. Донякъде тоя проблем го решавам с WML, като го разширявам с малко нестандартни функции. Евентуално някой ден може да имплементирам и WML Script, ама и това е друга бира ;-)


Съб Фев 27, 2010 10:06 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Аз не съм с толкова богат опит. С++ за МЦУ ползвах в един проект, който наследих и доразвих в последствие. Но имаше моменти, когато бях тактично посъветван да не си губя времето и да праскам на чисто С. Запазих нещата които ми харесваха, които бях разбрал какво вършат и какво не и това е. В последствие следващите ми проекти са на С с ала С++ стил :D. Но мнооого окастрено С++. Мисля че за тебе Миро ще е най-добре да не навлизаш в чак такива усукани конструкции, които биха накарали дори разработчиците на компилатора да се чешат по врата и да гледат с любопитство как се е справило отрочето им :)

_________________
Най-опасният враг на истината и свободата е мнозинството.


Нед Фев 28, 2010 12:41 pm
Профил
Ранг: Популярен
Ранг: Популярен
Аватар

Регистриран на: Сря Окт 11, 2006 8:19 pm
Мнения: 373
Местоположение: София/Edinburgh, UK
Мнение 
По стечение на обстоятелствата от две години май пиша главно на С# за PC, когато човек му свикне на езика разбира колко е полезен. За бързодействието лесно се докарва код да работи бързо колкото С (тествал съм главно за imageprocessing приложения). Сега имам курсова работа на С++ и чак сега разбрах колко насилствено е заложен ООП подхода в С++. Просто, за да направиш нещо като да викнеш изрично конструктор за даден обект трябва поне да предефинираш = оператора...Това което miro_atc го каза е много вярно, С++ просто наследява С и предлага някаква възможност за ООП, която обаче далеч не предлага пълната сила на обектното програмиране. Но с трупането на проектите, които съм писал, се убеждавам, че най-важно е абстрактното представяне на проблема. Ако то е подходящо дори и с най-калпавия обектно-ориентиран език ще може да се имплементира така, че да работи стабилно, но не казвам, че ще бъде кратко :)

_________________
Българският портал за РОБОТИКА


Нед Фев 28, 2010 1:18 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Нед Яну 18, 2009 1:28 pm
Мнения: 110
Мнение 
sv_shady написа:
По стечение на обстоятелствата от две години май пиша главно на С# за PC, когато човек му свикне на езика разбира колко е полезен. За бързодействието лесно се докарва код да работи бързо колкото С (тествал съм главно за imageprocessing приложения). Сега имам курсова работа на С++ и чак сега разбрах колко насилствено е заложен ООП подхода в С++. Просто, за да направиш нещо като да викнеш изрично конструктор за даден обект трябва поне да предефинираш = оператора...Това което miro_atc го каза е много вярно, С++ просто наследява С и предлага някаква възможност за ООП, която обаче далеч не предлага пълната сила на обектното програмиране. Но с трупането на проектите, които съм писал, се убеждавам, че най-важно е абстрактното представяне на проблема. Ако то е подходящо дори и с най-калпавия обектно-ориентиран език ще може да се имплементира така, че да работи стабилно, но не казвам, че ще бъде кратко :)


нещо генерално не си разбрал :)

... и не ми се влиза в детайли - да оборвам всяко от горните твърдения !


Нед Фев 28, 2010 2:52 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Юли 31, 2007 2:55 pm
Мнения: 1792
Местоположение: София
Мнение 
Що се хабите? Мъдрият човек е казал преди много десетилетия че на всеки език може да пише като на Фортран (или асемблер). :P


Пон Мар 01, 2010 3:33 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 32 мнения ]  Отиди на страница Предишна  1, 2, 3  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни