View Full Version : [c/c++]Ridefinire una funzione di libreria
Salve,
il mio obiettivo è di riuscire a ridefinire una funzione della libreiria del c, ad esempio la funzione exit( int ) che provoca l'uscita dal programma e che è definita in stdlib.h. Supponiamo che quando viene chiamata exit(n) io voglia eseguire una mia funzione myexit(n).
Per fare ciò ho definito un file stdlib.h che ho messo nella cartella locale del mio programma, e in cui importo la vera stdlib.h e subito dopo ridefinisco exit con myexit:
#ifndef MYSTDLIB_H
#define MYSTDLIB_H
//Con questa istruzione includo la libreria originaria; la
//includo riferendola col percorso completo per non confonderla
//col mio file stdlib.h
#include "/usr/include/stdlib.h"
//dichiaro il prototipo della mia funzione
void myexit(int);
//ridefinisco exit con myexit
#define exit myexit
#endif // MYSTDLIB_H
L'implementazione della myexit è quindi messa in un file .c . Ora se nel mio programma includo <stdlib.h> e chiamo exit viene sempre eseguita la funzione standard della libreria. Come posso fare invece per far eseguire la mia?
Analogamente vorrei ridefinire una macro, assert, definita in asssert.h.
Grazie e ciao.
Metti l'include alla stdio.h originale nel file .c dove definisci la tua exit...il problema è che chiaramente sei costretto a ridefinire anche tutte le altre funzioni ;)
Perche sono costretto a ridefinire tutte le funzioni? Nel mio stdlib.h faccio l'include all'originale stdlib.h, quindi le altre funzioni dovrebbero essere normalmente visibili.
Comunque non è questo il problema, il problema è che comunque nel mio programma viene importata la libreria originale e non la mia, come faccio a fargli importare la mia, fermo restando che nel programma ci deve essere comunque l'istruzione:
#include <stdlib.h>
Allora non puoi farlo se nel programma deve rimanere #include <stdlib.h>
A meno di modificare lo stdlib.h originale...
ma nn c'era na funz on_exit((*void)()) che permetteva di usare una funz per pulire???
O è solo del GCC/Glibc?
ecco qui:
int atexit (void (*function) (void)) Function
The atexit function registers the function function to be called at normal program termination. The function is called with no arguments.
The return value from atexit is zero on success and nonzero if the function cannot be registered.
Esempio:
#include <stdio.h>
#include <stdlib.h>
void
bye (void)
{
puts ("Goodbye, cruel world....");
}
int
main (void)
{
atexit (bye);
exit (EXIT_SUCCESS);
}
Originariamente inviato da Luc@s
ma nn c'era na funz on_exit((*void)()) che permetteva di usare una funz per pulire???
O è solo del GCC/Glibc?
E' ANSI...ma non so se sia questo quello che vuole fare...
Originariamente inviato da cionci
E' ANSI...ma non so se sia questo quello che vuole fare...
magari lo aiuta.
Se no deve fare npo di casino
Nella soluzione suggerita da Luc@s se ho ben capito, si dice di richiamare una certa funzione all'uscita dal programma, però non mi permette di ridefinire la exit, cioè di rimpiazzarla completamente. In pratica io vorrei impedire l'uscita dal programma attraverso la exit.
Comunque al momento sarei piu interessato alla questione simile di ridefinire la macro assert che è definita in assert.h e che funziona cosi:
assert(condizione)
se condizione è true non succede nulla, se no viene stampato un messaggio d'errore e si invoca una funzione per uscire dal programma, mi sembra "abort".
Io vorrei ridefinire la macro assert in modo tale che non le faccio chiamare la funzione abort cosi non esco dal programma. Anche in questo caso assert.h è un file header della libreria del e viene incluso con
#include <assert.h>
Cioè come dovrei usare undef?
Il mio obiettivo è riuscire a fare tutto senza toccare i sorgenti in cui vengono usate exit ed assert, ma riuscire a fare tutto in qualche altro modo, appunto definendo degli altri file con lo stesso nome degli header di libreria
Per la exit lo puoi fare solo se metti mano a stdlib.h (a quella originale)...almeno credo...
Per assert se èuna macro puoi scrivere:
#undef assert
e poi rifai il #define come ti pare a te...
Se scrivo undef assert e poi la ridefinizione nel file stesso che usa la assert funziona, io pero come ho detto volevo riuscire a fare la cosa senza toccare quel file, che si limita ad importare assert.h e volevo quindi riuscire ad oscurare l'originale assert.h con un mio assert.h che importa l'originale e poi fa l'undef e ridefinisce la macro; pero se faccio viene sempre visto l'assert.h originale, nonriesco ad oscurarlo.
Chiaro...come fa il compilatore a discriminare quale assert.h prendere ? Magari c'è qualche parametro da passare al compilatore, ma non ne sono a conoscenza...
Mi pare che il prof mi avesse detto che il compilatore cercava prima nella directory corrente e poi nel path delle librerie del gcc, ma invece sembra che faccia il contrario
Sembra che l'opzione -I <percorso dei file header> faccia al caso mio ;)
uhm,se non vuoi guai è meglio non toccare le librerie.
Forse non ho capito bene ma io mi farei la mia funzione on_exit o similare che ha come parametro un puntatore a funzione(cioè l'operazione da compiere all'uscita) e che termina con l'exit standard.
Ma vedo ora che puoi adoperare anche il c++ e in questo caso una funzione con un template di function-object come parametro sarebbe senz'altro + elegante.
No, le funzioni di libreria non le tocco, anche per il fatto che questa cosa mi serve sono per uno specifico programma; comunque sono riuscito appunto a risolvere passando al compilatore l'opzione
-I .
con cui dico al compilatore di cercare i file header prima nella directory corrente in cui ho il mio stdlib.h che include quello originale.
Registrare delle funzioni da chiamare all'uscita del programma non mi basta perche il mio obiettivo è propio impedire l'uscita dal programma causato dalla exit,
OT x Verloc: se sei pratico di template tra un po posterò un thread per sapere se coi template posso ridefinire la malloc attraverso una funzione mymalloc parmetrica rispetto al tipo di ritorno; se puoi dacci uno sguardo ;)
Utilizzando l'opzione -I . con cui dico al compilatore di cercare i file header prima nella cartella locale sono riuscito a ridefinire la macro assert definendo un mio file assert.h all'intenro del quale ridefinivo assert come mi pare a me.
Ora pero con la exit nonriesco a fare la stessa cosa: ho fatto un file locale stdlib.h:
//Con questa istruzione includo la libreria originaria; la
//includo riferendola col percorso completo per non confonderla
//col mio file stdlib.h
#include "/usr/include/stdlib.h"
//dichiaro il prototipo della mia funzione
void myexit(int);
//ridefinisco exit con myexit
#define exit myexit
pero nel progrmma se chiamo exit viene sempre vista la funzione della libreira standar; perchè avviene questo se ho messo la macro
#define exit myexit
prima di compilare non dorebbe sostiuire le occorrenze di exit del mio programma con myexit??? Se la macro la metto esplicitamente nel programma funziona, ma io vorrei che fosse automaticamente includsa dal mio file stdlib.h
ilsensine
20-04-2004, 16:26
Non so se fa al caso tuo, ma un modo semplice (che non richiede neanche di modificare il programma!) è creare una libreria .so con la tua funzione exit() modificata; quindi, per "sostituirla" a quella usata da un programma qualsiasi, invochi il programma con:
LD_PRELOAD=libmyexit.so <nome programma>
Per creare una libreria .so da un file .c puoi fare così:
Prima ti crei il file oggetto (non l'eseguibile!)
gcc -c -o file.o file.c
infine lo linki in una libreria dinamica:
ld -shared -o libmyexit.so file.o
Quindi sposti libmyexit.so in una dir di sistema (ad es. /usr/lib).
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.