Jump to content

Padot fukciju kā parametru struktūras "loceklim" c++


Jurkins
 Share

Recommended Posts

Labs rīts visiem!

enum mType
{
    CONT,
    MEMB,
    APPL,
};

uint8_t function_1(uint8_t val);
uint8_t function_2(uint8_t val);

struct menuItem
{
    mType type;
    //void (*function_1)(uint8_t val);
    char* title;
    void* child;
    uint8_t count;
};

const char mon[] = "Pirmdiena";
const char tue[] = "Otrdiena";

menuItem item1 = {MEMB, (char*)mon, (void*)&function_1, 5};
menuItem item2 = {MEMB, (char*)mon, (void*)&function_2, 3};

int main()
{
  menuItem *currentItem = &item1;
  cout << (int) (*currentItem->child)(currentItem->count) << endl;
  cout << (int) (*function_1)(currentItem->count) << endl;
  
  currentItem = &item2;
  cout << (int) (*currentItem->child)(currentItem->count) << endl;
  cout << (int) (*function_2)(currentItem->count) << endl;
}

uint8_t function_1(uint8_t val)
{
    return val--;
}
uint8_t function_2(uint8_t val)
{
    return val++;
}

Tātad situācija. Ir struktūra, kuras vienam elementam (void* child) gribu iebarot pointeri uz fukciju. Vispārīgi, ko šim elementam iebarot, ir atkarīgs no tā , kāds ir mType type. Vienā gadījumā man tur vajag iebarot pointeri uz citu šādu pašu struktūru. Tur viss iet bez problēmām. Bet šeit kompilators saka, ka;

45:32: error: 'void*' is not a pointer-to-object type

49:32: error: 'void*' is not a pointer-to-object type

Es pat saprotu :), ka šis ir malacis, ka tā saka, un kāpēc šis tā saka. Bet kā šajā gadījumā "pievest" *currentItem->child tipu? Jeb es jau no sākuma kaut ko daru nepareizi, un to "iebarošanu" vajag veikt kaut kā citādi. Gūgles tantes dotajās pamācībās, struktūrā vienmēr ir pointeris uz konkrētu funkciju, kā aizkomentētajā rindā. Bet tas neder :(.

Iepriekš paldies, par Jūsu laiku un sapratni par manu c++ nevīžibu :).

 

 

Link to comment
Share on other sites

Paldies par linkiem. Nezin kāpēc gūglē šie nav pirmajās lapās. Mācos.

Bet tātad, cik pašreiz saprotu, ja piem. ir definēta struktūra, kurā ir pointers uz funkciju :
 

struct MyStruct
{
	...
	void *func;
	...
};

typedef uint8_t(*ptr2func1)(uint8_t, uint8_t);
typedef uint8_t(*ptr2func2)(uint8_t);
typedef void   (*ptr2func1)(uint16_t);

Un man ir funkcijas ar dažādiem prototipiem, tad iebarojot "pievestas" ar (void*) vērtības objektiem ar šo struktūru:

uint8_t func1(uint8_t val){...};
uint8_t func2(uint8_t val1, uint8_t val2){...};
void    func3(uint16_t val){...};

MyStruct item1 = {...,(void*)&func1, ...};
MyStruct item2 = {...,(void*)&func2, ...};
MyStruct item3 = {...,(void*)&func3, ...};

Pēc tam es varu "pievest" tipu atpakaļ (vienā rindiņā bez tiem tmp... nesanāk):

...
ptr2func1 *tmp1 = (ptr2func1*)item1.func;
cout << (*tmp1)(96) << endl;
ptr2func2 *tmp2 = (ptr2func2*)item2.func;
cout << (*tmp2)(68, 56) << endl;
ptr2func3 *tmp3 = (ptr2func3*)item2.func;
(*tmp3)(32450);

Bet man jāzin, kuru reizi kura funkcija tiek lietota.

Vai ir kāds veids, kā likt kompilatoram pašam saprast?

"union" definējot struktūru un padodot nevis kā (void*)&func1, (void*)&func2, (void*)&func3 bet kā (ptr2func1*)&func1, (ptr2func2*)&func2, (ptr2func3*)&func3?

Mēģināju, bet kaut kas nesanāca ar union. Pagaidām...

Link to comment
Share on other sites

AndrisBB
pirms 1 stundas , Jurkins teica:

Pēc tam es varu "pievest" tipu atpakaļ (vienā rindiņā bez tiem tmp... nesanāk):

Varbūt tapēc ka structā tev ir parasts void pointers un bez pārveidošanas kompailers nevar zināt ka tas ir funkciju pointers?

 

http://blog.frama-c.com/index.php?post/2013/08/24/Function-pointers-in-C

Labots - AndrisBB
Link to comment
Share on other sites

Es biju domājis, ka nevar uzrakstīt :

cout << ((ptr2func2*)item2.func)(68, 56) << endl;

laikam sintakse neļauj, vai es neprotu iekavas ielikt, kur vajag.

To void pointeru es structā lieku apzināti, jo citā gadījumā vajag tur iedot pointeri ne uz funkciju.

Link to comment
Share on other sites

AndrisBB
pirms 1 stundas , Jurkins teica:

struct MyStruct { ... void *func; ... };

 

pirms 1 stundas , Jurkins teica:

MyStruct item1 = {...,(void*)&func1, ...};

 

Pietam manuprāt nav laba doma (un arī nav atļauts pēc standartiem) castot funkciju poiteri uz void pointeri (datu pointeri), jo uz vienas platformas tas ies, bet uz citas nē. Piemēram kods un dati var būt dažādos atmiņas reģionos.   

Link to comment
Share on other sites

Any way... ja topošais programmētājs neprot no google uzzināt šitik elementāru lietu - klau, piedod, bet nu domā par kādu citu amatu, vienkārši nav talants un pareizā domāšana :( Nemoki sevi...

 

Link to comment
Share on other sites

AndrisBB

Pilnīgās auzās tā castošana var aiziet uz AVR, jo void pointers būs 8 biti, kamēr funkciju pointers būs 16 biti, tā ka tu structā viņu nemaz neieliksi

Kautkādu workaroundu tu vari uztaisīt ar pointeri uz pointeri, kurš pointo uz dažādām struktūtām (viens uz structu ar datiem, cits uz structu ar tev vēlamo funkciju), bet tā čakars, tik sapīties var, izdomā labāk kādu pavisam savādāku risinājumu.

Labots - AndrisBB
Link to comment
Share on other sites

(labots)

Ok, paldies AndrisBB, spinnim mozgom jau bija čujs, ka nepareizi daru. Vai ar union šo lietu būtu pareizāk darīt?

Nu līdz workaroundiem man vēl jātiek...:)

 

rubb!!! "topošajam programmētājam" drīz būs 50, tas ir tīri hobijs, kurš 100% nekad nekļūs par amatu vai maizesdarbu. Tā kā nesatraucies. Jā, varbūt nav talants un pareizā domāšana - pats jūtu, ka nav tas, kad bija 20 un integrāļus un difvienādojumus kodu tikai tā. Jā, ir bišķi škrobe, ka dzīve pagriezās tā, ka aizgāju prom no programmēšanas un elektronikas. Īsi sakot, ja nav ko teikt, tad aizveries!

Labots - Jurkins
Link to comment
Share on other sites

AndrisBB

Kāds vispār ir šim visam mērķis? Jo izskatās ka tu mēģini kautko vienkāršu atrisināt sarežģīti.

On 01/04/2017 at 9:27 AM, Jurkins teica:

Tātad situācija. Ir struktūra, kuras vienam elementam (void* child) gribu iebarot pointeri uz fukciju. Vispārīgi, ko šim elementam iebarot, ir atkarīgs no tā , kāds ir mType type. Vienā gadījumā man tur vajag iebarot pointeri uz citu šādu pašu struktūru. Tur viss iet bez problēmām. Bet šeit kompilators saka, ka;

Kapēc nevar atstāk child kā pointeri uz tādu pašu struktūru, un pielikt otru pointeri, kurš ved uz funkciju? Ja child ir null, tad tiek izsaukta funkcija.

Vai arī definē funkciju, kura kā parametru saņem tavu struktūru un tur veic nepieciešamās lietas. Grūti saprast ko tu gribi panākt.

  • Patīk 1
Link to comment
Share on other sites

(labots)

Jā, laikam jau tā ir, ka es mēģinu mandeles caur pakaļu operēt.

Šie struct ir izvēlnes punkti, kuri var būt kā konteineri - tas ir saturēt  (velns, saturēt nav pareizi teikts) apakšpunktu kopu, un tad es gribēju padod pointeri uz pirmo "child" elementu. Nu un tad man sākās "navaroti" . Izvēlnes punktiem, kuri vairs nesatur apakšpunktus, bet liek izpildīties kaut kādai funkcijai, gribēju padot pointeri uz šo funkciju. Teiksim tā, skriedams notikumiem pa priekšu un nezinādams, ar ko atširas pointeris uz funkcijuno pointera uz datiem. Tupa gribēju ekonomēt atmiņu.

Pirms 19 minūtēm , nevertell teica:

Kāpēc lietojam C++, ja tik ļoti gribās rakstīt C ?

Īsti pat nezinu, ko atbildēt. Man (nezinu vai pagaidām vai rubb ir taisnība :)) , bet C++ man nesanāca šos menu punktus kā objektus glabāt flešā nevis RAMā. Nu, esmu meklējumos. Tas, kas ir te, ir rakstīts iekš web c++ IDEs vienkārši lai saprastu, kas notiek, kā tie pointeri uz funkcijām strādā. Īstā aplikācija priekš atmeļa darbojas un ar enkoderu var staigāt pa punktiem, bet tagad vajag pievienot funkcijas klāt, un te nu sākās mana epopeja ar mandelēm caur pakaļu.

Labots - Jurkins
Link to comment
Share on other sites

AndrisBB

Nu ja tas ir atmelim, tad priekškam vispār C++ (naptīk man c++ :D), pietam kā jau te teicu, tad rezultāts būs savādāks kad kompilēsi priekš paša čipa.

Link to comment
Share on other sites

Cik nu es varu spriest, man c++ patīk "sakārtotība" - klases , hierarhija u.t.t. Bet nu dzīvosim, redzēsim.

Link to comment
Share on other sites

Izoperēju mandeles caur pakaļu ... daļēji. Ar union struktūrai iebarot smuki var gan pointeri uz funkciju gan pointeri uz tādu pašu struktūru. Un viss darbojas. Sliktums tikai tas, ka funkcijām jābūt ar vienādu prototipu. Var iebarot cik vajag funkciju prototipus, bet tas neko nedod, jo pēc tam darbojoties ar šo struktūru  masīvu, izmantojot kaut kādu:

struct Item *currentItem;

jāzina, kāds prototips kurā brīdī jāizmanto. Lai gan manām vajadzībām - atmeļprojektos tās izvēlnes jau nav nekādas sarežģītās, un, varbūt, pilnīgi pietiktu, ja kaut vai katrā izvēlnes zarā visi punkti palaiž funkcijas ar vienādiem prototipiem. Pieļauju gan ar lielu varbūtību, ka to izdarīt var, es tikai nezinu pagaidām.

Jebšu būs jāmeklē cits ceļš.

Link to comment
Share on other sites

Izveido kontu, vai pieraksties esošajā, lai komentētu

Jums ir jābūt šī foruma biedram, lai varētu komentēt tēmas

Izveidot jaunu kontu

Piereģistrējies un izveido jaunu kontu, tas būs viegli!

Reģistrēt jaunu kontu

Pierakstīties

Jums jau ir konts? Pierakstieties tajā šeit!

Pierakstīties tagad!
 Share

×
×
  • Izveidot jaunu...