Richiamo funzioni c da c++

Area di discussione libera.

Moderatore: Staff

Regole del forum
1) Rispettare le idee altrui.
2) Evitare le offese dirette.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
sir_alex
Linux 3.x
Linux 3.x
Messaggi: 735
Iscritto il: lun 21 mar 2005, 0:00
Kernel: 2.6.35-22
Desktop: KDE4
Distribuzione: Ubuntu
Località: Milano - Corbola (RO)
Contatta:

Richiamo funzioni c da c++

Messaggio 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?

epd20
Linux 0.x
Linux 0.x
Messaggi: 92
Iscritto il: lun 15 ago 2005, 0:00
Località: Aosta
Contatta:

Messaggio 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.. :wink:

Prova così...

Avatar utente
absinthe
Iper Master
Iper Master
Messaggi: 2354
Iscritto il: dom 15 mag 2005, 0:00
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze
Località: Prato
Contatta:

Messaggio 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.

epd20
Linux 0.x
Linux 0.x
Messaggi: 92
Iscritto il: lun 15 ago 2005, 0:00
Località: Aosta
Contatta:

Messaggio 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
:oops:
Emile

Avatar utente
TheSnowBoarder
Linux 1.x
Linux 1.x
Messaggi: 139
Iscritto il: gio 30 giu 2005, 0:00
Località: Catania

Messaggio 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

sir_alex
Linux 3.x
Linux 3.x
Messaggi: 735
Iscritto il: lun 21 mar 2005, 0:00
Kernel: 2.6.35-22
Desktop: KDE4
Distribuzione: Ubuntu
Località: Milano - Corbola (RO)
Contatta:

Messaggio 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!

Avatar utente
absinthe
Iper Master
Iper Master
Messaggi: 2354
Iscritto il: dom 15 mag 2005, 0:00
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze
Località: Prato
Contatta:

Messaggio 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.

epd20
Linux 0.x
Linux 0.x
Messaggi: 92
Iscritto il: lun 15 ago 2005, 0:00
Località: Aosta
Contatta:

Messaggio da epd20 »

Non ho proprio veramente ben capito del tutto completamente (etc etc :lol: ) la tua ultima "frase" :wink: però sì, avevo ragione, che credevi? :wink:

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! :wink: )
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++

Codice: Seleziona tutto


funzia_c(int);
...
while(funzia_c(3)==0);

diventa dopo passato nel compilatore

Codice: Seleziona tutto


funzia_c(int);
...
while(__H1zifunzia_c(3)==0);

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? 8)

Avatar utente
absinthe
Iper Master
Iper Master
Messaggi: 2354
Iscritto il: dom 15 mag 2005, 0:00
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze
Località: Prato
Contatta:

Messaggio da absinthe »

epd20 ha scritto:Non ho proprio veramente ben capito del tutto completamente (etc etc :lol: ) la tua ultima "frase" :wink: però sì, avevo ragione, che credevi? :wink:

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! :wink: )
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++

Codice: Seleziona tutto


funzia_c(int);
...
while(funzia_c(3)==0);

diventa dopo passato nel compilatore

Codice: Seleziona tutto


funzia_c(int);
...
while(__H1zifunzia_c(3)==0);

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? 8)
ok stiamo andando OT quindi metto l'ultimo post poi al limite ne discutiamo su un thread apposito o in pm.

:roll: 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.

Rispondi