Página 1 de 2

Como declarar um ponteiro p/ função inline em struct no C ?

MensagemEnviado: 03 Set 2016 16:21
por andre_luis
Pessoal,

Estou implementando uma estrutura que funciona normalmente, onde eu além de manipular variavel, consigo manipular função. Pura frescura, apenas pra organizar o programa, meio que pra ficar CPP-like colocando coisas similares dentro da mesma arvore, mas só consigo fazer isso em duas etapas do typedef:

cpp code
typedef   int8 (*Operation)(int8 address );

typedef struct DISPLAY {
int16 cDutyCycle ;
Operation show; // funtion pointer
} DSP7SEG_LED ;


Alguem saberia como possocolocar a 1a linha do código acima dentro da 5a linha ?
Tentei pela simples substituição da declaração do tipo acima dentro do tipo abaixo, mas não funcionou.

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 03 Set 2016 17:04
por denis
E se você colocar na 5a linha um ponteiro void, esse ponteiro recebe o endereço a sua função.
Aí quando você for chamar a função você faz um cast do ponteiro void para int8 (*Operation)(int8 address ).

Cara isso foi um chute, nem imagino se funcione, vou testar aqui. :D

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 03 Set 2016 17:19
por denis
Eu estava curioso pra saber se funcionava.

cpp code
#include <stdio.h>

void tst2(int a, int b)
{
printf("a %d - b %d \n", a,b);
fflush(stdout);
}

int main (int argc, char *argv[])
{
void *ptr_void;
void (*ptr_func)(int, int);

/* Aponta para função. */
ptr_void = &tst2;

/* Atribui o ponteiro fazendo o cast. */
ptr_func = (void(*)(int, int))ptr_void;

/* chama a funçao passando os parametros */
(*ptr_func)(2,3);

return EXIT_SUCCESS;
}

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 03 Set 2016 20:37
por andre_luis
Rapaz, obrigado pela sugestão, mas eu deveria substituir o tipo do ponteiro para void ?
Tentando aplicar a dica ao meu caso, aparentemente não funcionou.
Substitui o codigo anterior por isso:

cpp code
typedef  struct DISPLAY {
int16 cDutyCycle ;
void (*Operation)(int8 address ) show; // funtion pointer
} DSP7SEG_LED
;

...mas dá erro, ao meu ver por motivo obvio.

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 11:00
por tcpipchip

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 13:57
por denis
andre_teprom escreveu:Rapaz, obrigado pela sugestão, mas eu deveria substituir o tipo do ponteiro para void ?
Tentando aplicar a dica ao meu caso, aparentemente não funcionou.
Substitui o codigo anterior por isso:

cpp code
typedef  struct DISPLAY {
int16 cDutyCycle ;
void (*Operation)(int8 address ) show; // funtion pointer
} DSP7SEG_LED
;

...mas dá erro, ao meu ver por motivo obvio.


O que eu estava pensando:

cpp code
void tst2(int a, int b)
{
printf("a %d - b %d \n", a,b);
fflush(stdout);
}

typedef struct DISPLAY
{
int16_t cDutyCycle;
void *Ptr_Func_Generic;
} DSP7SEG_LED_t;

int main (int argc, char *argv[])
{
static DSP7SEG_LED_t DSP7SEG_LED;
void (*ptr_func)(int, int);

/* Preenche a estrutura. */
DSP7SEG_LED.cDutyCycle = 50;
DSP7SEG_LED.Ptr_Func_Generic = &tst2;

/* Atribui o ponteiro fazendo o cast. */
ptr_func = (void(*)(int, int))DSP7SEG_LED.Ptr_Func_Generic;

/* chama a funçao passando os parametros */
(*ptr_func)(2,3);


return EXIT_SUCCESS;
}


Mas o impacto disso é ter que fazer o cast do ponteiro genérico para o ponteiro de função na linha 23.

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 14:11
por andre_luis
http://stackoverflow.com/questions/1148 ... a-c-struct
Acredito que visitastes...
Repare que o foco da minha necessidade é a declaração inline, ou seja, tudo dentro do mesmo struct; As implementações alí pareceram um pouco mais complexas e usando mais etapas.

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 14:13
por denis
A sugestão do tcpipchip parece ser a mais adequada.

cpp code
void tst2(int a, int b)
{
printf("a %d - b %d \n", a, b);
fflush(stdout);
}

typedef struct DISPLAY
{
int16_t cDutyCycle;
void (*Ptr_func)(int, int);
} DSP7SEG_LED_t;

int main (int argc, char *argv[])
{
static DSP7SEG_LED_t DSP7SEG_LED;

/* Preenche a estrutura. */
DSP7SEG_LED.cDutyCycle = 50;
DSP7SEG_LED.Ptr_func = &tst2;

/* chama a funçao passando os parametros */
(*DSP7SEG_LED.Ptr_func)(2,3);

return EXIT_SUCCESS;
}

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 14:16
por andre_luis
denis escreveu:A sugestão do tcpipchip parece ser a mais adequada.


Hummm....beleza, vou testar, valeu

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 14:43
por Rodrigo_P_A
O que vc quer dizer com "inline" ? seria tipo isso?

cpp code
typedef struct
{
int16_t cDutyCycle;
void(*Ptr_func)(int, int, void *me);
} tp1;

void funcao(int x, int y, tp1 *me) {
int dutty;
dutty = me->cDutyCycle;
}

const tp1 f1 = { 1,funcao };
const tp1 f2 = { 2,funcao };
const tp1 f3 = { 3,funcao };
const tp1 f4 = { 4,funcao };

void teste() {
f1.Ptr_func(1, 2, &f1);
f2.Ptr_func(1, 2, &f2);
f3.Ptr_func(1, 2, &f3);
f4.Ptr_func(1, 2, &f4);
}

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 16:57
por andre_luis
Exatamente, eu gostaria de fazer a declaração de todo o struct dentro dele mesmo, como voce voce indicou.

O problema, é que do modo como está acima, isso muda a usabilidade atual do meu programa.
No caso, eu só gostaria de mexer na seção do typedef, nao no restante do programa.

cpp code
//Seçao que desejo alterar 
typedef int8 (*Operation)(int8 address );
typedef struct DISPLAY {
int16 cDutyCycle ;
Operation show; // gostaria de mexer somente aqui, mantendo compatibilidade c/ o programa
} DSP7SEG_LED ;

//Declaração da variavel global
DSP7SEG_LED LEDdsp7seg ;

//Atribuição do ponteiro dentro do Init()
LEDdsp7seg.show = Display7seg ;

//Utilização da estrutura nas rotinas:
LEDdsp7seg.show ('0') ; // exemplo para mostrar zero
LEDdsp7seg.cDutyCycle = 0 ; // valor minimo do duty


Observe que nas ultimas linhas do codigo acima, tal como em C++, eu trato tanto a funçao como a variavel do mesmo modo.

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 19:32
por barboza
Experimenta isso:

Código: Selecionar todos
typedef  struct
{
       int16  cDutyCycle;
       int8 (*show)(int8 address);
 } DSP7SEG_LED;

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 21:30
por andre_luis
Poisé, essa foi a primeira tentativa, mas dá o seguinte erro de compilação em cada linha onde a função é instanciada:

*** Error 53 "nomedoarquivo.c" Line 174(15,19): Expecting function name

Onde a função show fica destacada:
LEDdsp7seg.show( 0 ) ;

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 04 Set 2016 21:37
por barboza
Estranho, usamos isso com compilador ARM e roda liso.

Código: Selecionar todos
typedef struct
{
           t_en_dr18_FieldType en_Type;
           t_en_dr18_FieldFlags en_Flags;
   
           t_en_dr41_Fonts en_Font;
           u8 begx, begy;
   
           u8 count, numidx;
           u8 virtual, virtualidx;
   
           u8 *pu8_data;
   
           u8 (*pp_check)(u8 *pu8_data);
           void (*pp_update)(u8 u8_value);
           void (*pp_cancel)(void);
} t_st_mi39_Window;

...
t_st_mi39_Window st_mi39_Window[MI39_SCREEN_WINDOW_SIZE];
...

                                if ((st_mi39_Window[u32_Field_idx].pp_check) &&
                                        (st_mi39_Window[u32_Field_idx].pp_check(st_mi39_Window[u32_Field_idx].pu8_data)))
                                {
                                        p_mi43_Play_Tone(MI43_TONES_MENU, MI01_ERROR_TONE);
                                        return;
                                }
...

Re: Como declarar um ponteiro p/ função inline em struct no

MensagemEnviado: 05 Set 2016 12:48
por andre_luis
Bom, estou no CCS...e num microcontrolador de 8 bits...e da familia PIC16...e talvez explique, rsrsrs
Mas vou testar mais tarde quando estiver com o computador onde tenho o programa.

Obrigado.
AT+