paulo1205
(usa Ubuntu)
Enviado em 19/09/2012 - 15:32h
Você quer chamar uma função
f(), cujo tipo de retorno e tipos dos argumentos não batem com que uma determinada interface espera?
Você pode usar um daqueles
type-casts que praticamente distorcem o espaço-tempo e o deixa sujeito a assombrações. Por exemplo, para transformar um ponteiro para função qualquer num ponteiro de função que não recebe nem retorna coisa alguma -- um exemplo, portanto, extremamente simples, muito mais simples, certamente, do que qualquer coisa que lhe venha a ser útil -- você teria a seguinte sintaxe supertrivial.
int f(int x){ /* função exemplo */
x*=x; /* Não usual, mas válido, e só para ficar mais interessante. */
return x;
}
int call_func_ptr(void (*ptr_f)(void)){
ptr_f();
return 0;
}
int main(void){
/* Note o cast na linha abaixo. Claro como água cristalina, não? */
return call_func_ptr((void (*)(void))f);
/* Note que o compilador vai aceitar essa chamada, já que ptr_f diz *
* que não recebe argumento algum, mas nós sabemos muito bem que é *
* f() que será invocada no fim das contas, e omitindo-se o parâme- *
* tro que ela espera receber. O que vai acontecer é que a opera- *
* ção "*=" no corpo da função vai alterar o endereço de retorno ou *
* outra estrutura de controle da pilha. O resultado disso é im- *
* predizível, mas provavelmente será danoso. */
}
Ou então, você pode ser um pouco mais civilizado e humilde, e usar, em lugar de um cast que faça fingir que uma função é de um tipo diferente do que realmente é, criar uma função com o tipo desejado, chamando a função original manualmente dentro dessa segunda função. Nesse caso, o exemplo acima poderia ser reescrito como se segue.
int f(int x){ /* função exemplo */
x*=x; /* Não usual, mas válido, e só para ficar mais interessante. */
return x;
}
void f_wrapper(void){
f(0); /* Usa um valor dummy só para satisfazer o compilador. Ignora *
* o valor de retorno -- o que é comum em C. */
}
int call_func_ptr(void (*ptr_f)(void)){
ptr_f();
return 0;
}
int main(void){
return call_func_ptr(f_wrapper);
}