Newsgroup: it.comp.os.linux.development
Titolo: Linkare .c e .cpp

E' possibile linkare con gcc dei .o generati da linguaggi diversi, per
esempio .c e .cpp? Quali sono le chiamate inter-linguaggio supportate?
Immagino che da un .cpp io possa invocare qualunque funzione implementata in
un .c, ma in un .c presumo non si possano istanziare oggetti e invocare
metodi c++, vero? E se io molto brutalmente cambiassi l'estensione dei miei
.c in .cpp e li ricompilassi in C++ sarebbe pių facile?
Ringrazio anticipatamete tutti gli ayatollah che vorranno illuminarmi su
questioni cosė complesse.
Alex

 miei .c in .cpp e li ricompilassi in C++ sarebbe più facile?
Si puo' fare. Tieni presente che pero' non puoi richiamare metodi di classe 
C++ da un sorgente C;
Quello che puoi fare e' dichiarare ( in file C++ ) le funzioni come 'extern 
"C" { } '
Insomma guarda qua':
----------------------------------------
ghigo@sphera:/tmp$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-linux/2.95.2/specs
gcc version 2.95.2 20000220 (Debian GNU/Linux)                              
ghigo@sphera:/tmp$ cat prova.h
/* prova.h */
#ifdef __cplusplus
extern "C" {
#endif
        void fcpp( void );      /* funzione C++ */
        void fc( void );        /* funzione C */
#ifdef __cplusplus
}
#endif
ghigo@sphera:/tmp$ cat prova.c
/* prova.c */
#include <stdio.h>
#include "prova.h"
void fc( ){ printf("fc( )\n"); }
 
int main( ){
        fcpp( );
        return 0;
}
 
ghigo@sphera:/tmp$ cat prova.cc
// prova.cc
 
#include <iostream>
#include "prova.h"
 
//using namespace std;
 
class A {
        public:
                void f( ) { cout <<"A::f( )" << endl; }
};
 
void fcpp( ){
        class A a;
        a.f( );
        fc( );
}
ghigo@sphera:/tmp$ gcc -Wall -o provac.o -c prova.c
ghigo@sphera:/tmp$ gcc -Wall -o provacc.o -c prova.cc
ghigo@sphera:/tmp$ g++ -o prova provac.o provacc.o
ghigo@sphera:/tmp$ ./prova
A::f( )
fc( )
ghigo@sphera:/tmp$
---------------------
In cui
        prova.h                 header comune ai due file
        prova.cc                file c++
        prova.c                 file c
La funzione *C* main( ) richiama la funzione *C++* fcpp( ) che richiama 
metodi C++ ( cout e un metodo di una classe A ( a::f( ) ) ) e una funzione 
*C* ( fc( ) ).
Le uniche accortezze sono:
        - nei file C++ devi definire le funzioni che vuoi utilizzare anche 
          in C con
          extern "C" { ... }. Nota che io ho dovuto nascodere il tutto 
          sotto dei 
          '#ifdef __cplusplus' altrimenti questo costrutto appariva anche nei
          sorgenti 'C' ( in cui e' illegale ). 
        - Ricordati di linkare anche le librerie C++ ( per questo io ho 
          linkato il tutto con 'g++' )
 
 

...
Alex Baretta ha scritto:
...
Grazie. Prima di tutto un sonoro vaffanculo a zio Bill! Ti rendi conto che
Outlook non mi fa quotare a 70 caratteri e con le " > " a inizio riga? Le
preferenze che l'utente setta in "Opzioni" cosa sono: un sondaggio per
migliorare il prodotto nella prossima versione?!
OK! No grazie, troppo complicato... Avrei voluto definire delle funzioni
generiche in C++ da richiamare in C, ma dovrei istanziarle, e questo in C
non si fa... Ho trovato il modo di aggirare il problema. Il trucco viene
usato dal gcc stesso per definire in modo generico le funzioni matematiche
che devono operare in modo uniforme su float, double, long double, long long
double.... Si tratta di utilizzare delle macro parametriche che
sostituiscono i nomi dei tipi nel testo della funzione
typedef float float_t;
typedef double double_t;
typedef long double l_double_t;
typedef long long double ll_double_t;
#define SOMMA_GENERICA ( tipo ) \
tipo somma_di_/**/tipo (tipo x, tipo y) { return (x+y); }
Con un trucco di questo genere ho risolto il mio problema. Non è elegante,
non è ingegneristicamente corretto, ma
...This is a dirty job, but someone's gotta do it!
Alex