Pagina 1 di 1
Richiamo funzioni c da c++
Inviato: lun 15 ago 2005, 14:49
da sir_alex
Allora, sto provando a chiamare funzioni che ho su files c da un programma c++: ho creato il programmino di kdevelop di default in c++, quello con hello world grafico nella finestra creata in qt; poi ho aggiunto al progetto un file c (e relativo h) con una funzioncina stupidotta che si limita a stampare su stdout una frasetta, poi sono andato nella funzione button_clicked() che viene richiamata dal pulsante della finestra, ed ho aggiunto una chiamata alla funzione in c (dopo aver aggiunto il file h), chiamandola come faccio in c (ovvero, in questo caso, StampaDebug());
tutto si compila ma al momento del linking mi dà undefined reference to StampaDebug()... allora, premesso che so pochissimo di c++, c'è un modo particolare per chiamare una funzione scritta in c?
Inviato: lun 15 ago 2005, 15:12
da epd20
Dovresti dichiarare le funzioni C come extern "C".
Ad esempio:
extern "C" {
void funzione_scritta_in_c(int a);
}
Questo per una questione di name mangling...o qualcosa del genere, i miei corsi di C/C++ non sono più freschissimi..
Prova così...
Inviato: lun 15 ago 2005, 18:37
da absinthe
ma scusa compili separatamente i due files? c e c++? perchè il c++ ha un suo sottogruppo c che fa -salvo dettagli- esattamente le stesse cose del c... forse i files hanno estensioni diverse e il gcc/g++ le compila diversamente se il problema si verifica solo in fase di linking...
hai provato a dare la stessa estensione ai files?
dare
extern "C"
serve per creare un file c++ in cui si vuole che la sintassi (e probabilmente i nomi delle funzioni da linkare?) usata per una funzione del sottogruppo c sia intesa come quella di una funzione c pura. esempio:
in c
void FunzioneInutile ();
ha infiniti argomenti
nel sottogruppo c del c++ la stessa dichiarazione ha 0 argometni. indicando
extern "C"
abiliti la convenzipone c originale e probabilmente puoi linkare il file del sottogruppo c del c++ ad un file c (cioè l'opposto del tuo problema).
in breve _SE NON RICORDO MALE_... dando la stessa estensione ai files tutto dovrebbe essere compilato/linkato senza problemi.
ciao,
M.
Inviato: lun 15 ago 2005, 22:01
da epd20
Scusa,
in effetti forse non ho capito: extern "C", davanti ad una (o ad un grupo, racchiuso da graffe) funzione, la fa leggere come funzione C, ma questo ti è utile se la tua funzia è all'interno del file C++.
Se scrivi due files diversi non so che suggerirti..
Mi spiace
Emile
Inviato: mar 16 ago 2005, 15:58
da TheSnowBoarder
Per richiamare una funzione C da un codice C++
ti consiglio di fare quanto segue:
crea un file .c e .h per la singola funzione che
credi di implementare in C.
Edita il .h in questo modo:
#ifndef FOOBAR_H
# define FOOBAR_H
# ifdef __cplusplus
extern "C" {
# endif
extern void foobar(void);
# ifdef __cplusplus
}
# endif
Per ottenere l'eseguibile, compila separatamente i due file:
$ gcc foobar.c -c
$ g++ main.cc
quindi effettui il linking con
$ g++ foobar.o main.o -o foobar
Inviato: mar 16 ago 2005, 21:52
da sir_alex
Grazie dei consigli! Al momento ho risolto chiamando il file cpp anzichè c ma scrivendolo comunque in c, funziona... proverò anche il consiglio di TheSnowBoarder!
Inviato: mer 17 ago 2005, 13:05
da absinthe
TheSnowBoarder ha scritto:Per richiamare una funzione C da un codice C++
ti consiglio di fare quanto segue:
crea un file .c e .h per la singola funzione che
credi di implementare in C.
Edita il .h in questo modo:
#ifndef FOOBAR_H
# define FOOBAR_H
# ifdef __cplusplus
extern "C" {
# endif
extern void foobar(void);
# ifdef __cplusplus
}
# endif
Per ottenere l'eseguibile, compila separatamente i due file:
$ gcc foobar.c -c
$ g++ main.cc
quindi effettui il linking con
$ g++ foobar.o main.o -o foobar
anvedi ficooo....
cioè in pratica se ho ben capito con un file così, se sei in ambiente c++ usi extern per impiegare le convenzioni c classiche mentre se sei in ambiente c tutto fila liscio di suo... oppure non ci ho capito una mazza??? comunque non manca un #endif alla fine?!?
ma sopratutto. io credevo che con extern si potesse linkare a codice c delle funzioni del sottogruppo c del c++ non il viceversa... interessante... allora avevca ragione pure epd20? aiuto mi sto annodando...gosh....
M.
Inviato: mer 17 ago 2005, 13:26
da epd20
Non ho proprio veramente ben capito del tutto completamente (etc etc

) la tua ultima "frase"

però sì, avevo ragione, che credevi?
Scusa riassumo:
extern "C" dichiara,
all'interno di un file C++, una funzione
C con sintassi
C
vedi
http://howtos.linux.com/howtos/C++-dlop ... tion.shtml
e per quanto riguarda il name mangling (ricordavo bene... strano!

)
http://en.wikipedia.org/wiki/Name_mangl ... in_C.2B.2B
perchè il compilatore C++ aggiunge, attaccate alle funzioni, in fase di compilazione, "__##etcetc" a seconda dei compilatori e degli argomenti delle funzioni per distinguere, ad esempio, una funz con argomento int dalla funz con stesso nome ma argomento void.
e.g.
in C++
diventa dopo passato nel compilatore
con compilatore Gcc 3.x -non è proprio così semplice la funzione decorata ma è per rendere l'idea-
mentre, se la tua è una funzione C, non vuoi che ciò accada (non troveresti le funzioni nelle librerie C)!
Se la dichiari quindi extern "C" il compilatore se ne accorge e evita di aggiungere le "decorazioni".
Se poi fai come hanno suggerito i controlli con #ifdef(__cplusplus) è ancora meglio!
Tutto chiaro?

Inviato: mer 17 ago 2005, 13:58
da absinthe
epd20 ha scritto:Non ho proprio veramente ben capito del tutto completamente (etc etc

) la tua ultima "frase"

però sì, avevo ragione, che credevi?
Scusa riassumo:
extern "C" dichiara,
all'interno di un file C++, una funzione
C con sintassi
C
vedi
http://howtos.linux.com/howtos/C++-dlop ... tion.shtml
e per quanto riguarda il name mangling (ricordavo bene... strano!

)
http://en.wikipedia.org/wiki/Name_mangl ... in_C.2B.2B
perchè il compilatore C++ aggiunge, attaccate alle funzioni, in fase di compilazione, "__##etcetc" a seconda dei compilatori e degli argomenti delle funzioni per distinguere, ad esempio, una funz con argomento int dalla funz con stesso nome ma argomento void.
e.g.
in C++
diventa dopo passato nel compilatore
con compilatore Gcc 3.x -non è proprio così semplice la funzione decorata ma è per rendere l'idea-
mentre, se la tua è una funzione C, non vuoi che ciò accada (non troveresti le funzioni nelle librerie C)!
Se la dichiari quindi extern "C" il compilatore se ne accorge e evita di aggiungere le "decorazioni".
Se poi fai come hanno suggerito i controlli con #ifdef(__cplusplus) è ancora meglio!
Tutto chiaro?

ok stiamo andando OT quindi metto l'ultimo post poi al limite ne discutiamo su un thread apposito o in pm.

no non è chiaro...
che l'uso di extern c serva per "eliminare" le decorazioni che dici tu sono d'accordo, ma questo fa sì che il sottogruppo c sia compilato come un gruppo c. a me il problema sembrava l'opposto: tanto per dirla in maniera barbara ma concisa...
non è il problema di rimuovere una decorazione per usare funzioni del sottogruppo c all'interno di un applicativo in c puro, è il problema di come usare una funzione non decorata dal c++ all'interno di un applicativo in cui tutto il resto è decorato in stile c++...
io avevo sempre usato un'estensione comune tra i files, quindi ero incuriosito da sta storia delle flag per ottenere lo stesso risultato... ma mi ci sto fondendo quel poco di cervello che mi è rimasto...eheheh
-------------------------------------modifica
ok sono un imbecille. funziona anche al contrario: si può avvertire il c++ che quella definizione è associata ad un file oggetto compilato in c puro... mi ci vogliono un paio di corone stasera
:mrgreen:
M.