Sto pensando a come i programmatori mischiano le lingue.
Se voglio mescolare il linguaggio C e C ++, allora cosa dovrei fare?
E come mescolare le lingue?
Sto pensando a come i programmatori mischiano le lingue.
Se voglio mescolare il linguaggio C e C ++, allora cosa dovrei fare?
E come mescolare le lingue?
Beh, in primo luogo, C è più o meno un sottoinsieme di C ++, quindi c'è un sottoinsieme delle due lingue che sarà facilmente compilabile in entrambi i compilatori di lingue.
Oltre a ciò, le lingue parlano tra loro principalmente attraverso le API (Application Program Interfaces) e le interfacce di funzione esterna (FFI).
Un esempio di due lingue che parlano attraverso un'API è un oggetto JSON inviato a un servizio Web da Javascript in un browser Web a un micro-servizio scritto in Java.
Un esempio di due lingue che parlano attraverso una FFI è Python che parla con una libreria C. Molte lingue hanno un C FFI.
Sto postando una risposta aggiuntiva per aggiungere ulteriori dettagli utili non presenti nella risposta di Robert Harvey .
Molte lingue hanno diversi modi di comunicare con altre lingue, tutto dipende dalla relazione tra le due codebase. Alcune delle possibilità esistenti:
Lingue basate sullo stesso ambiente - proprio come puoi facilmente chiamare le funzioni C da C ++, ambienti come Java Virtual Machine (Java, Scala) o Common Language Runtime (C #, VB.NET) consentono per comunicare facilmente con il codice scritto in qualsiasi lingua che compili nello stesso ambiente. Tutte le librerie devono essere compatibili, quindi è possibile utilizzare facilmente la stessa base di codice per rendere più semplice la "conversazione con un altro programma". È anche possibile includere semplicemente il programma in una lingua diversa come una biblioteca per il progetto in un'altra lingua. L'integrazione è per lo più senza soluzione di continuità.
Motori e linguaggi di scripting : molte lingue dispongono di librerie che consentono di integrare i motori di scripting nel codice. Molto spesso, puoi scegliere oggetti e metodi che saranno visibili per il motore di scripting, permettendogli di comunicare con il tuo programma 'principale' e utilizzare le stesse librerie. Il vantaggio principale di questo approccio è che è possibile avere parti del codice che possono essere modificate al volo senza la necessità di ridistribuire o riavviare l'applicazione, ma - se si desidera esporle al di fuori dell'applicazione - si rischia una sicurezza elevata rischio. Richiede anche un po 'di lavoro.
Per gli rapporti tra API e e bridge tra due diversi ambienti , fai riferimento alla risposta accettata di Robert Harvey.
Ovviamente, non è possibile mescolare più lingue nello stesso file sorgente (a meno che non si scriva una voce IOCCC).
Come jk e reinierpost sottolineano nei commenti qui sotto, ci sono modi per mescolare lingue diverse nello stesso file sorgente, ma richiedono una sintassi speciale, parole chiave o passaggi di pre-elaborazione per farlo. Ad esempio, gcc offre un'estensione che ti consente di mescolare assembler e C nello stesso file sorgente usando una speciale parola chiave asm
:
void foo( void )
{
// some C code
asm( "movl %ecx,%eax\n\t"
"movl $0xff,%ebx\n\t"
"int $0x80\n\t"
...
);
// some more C code
}
Ciò che non puoi fare è scrivere
void foo( void )
{
// some C code
movl %ecx, %eax
movl $0xff, %ebx
int $0x80
...
// more C code
}
e compilarlo come codice C . Assente la parola chiave asm
, il compilatore C si bloccherà sulla prima riga dell'assembler.
Ho anche usato SQL direttamente incorporato nel codice C - in quei casi, dovevi usare parole chiave speciali ( EXEC SQL
) e dovevi eseguire il file sorgente attraverso un preprocessore, che converrebbe l'SQL in codice C valido. Quindi passeresti il codice sorgente preelaborato al compilatore C.
Ancora, ciò che non puoi fare è semplicemente mescolare il codice SQL e C nello stesso file sorgente e compilarlo come C (o eseguirlo come SQL ).
Per le situazioni in cui non è supportato il mixaggio della lingua in linea, è possibile scrivere file sorgente separati in lingue diverse, compilarli in file di oggetti separati e quindi collegare insieme i file oggetto in un singolo programma. Quanto è facile farlo dipende dalle lingue coinvolte e dalle loro convenzioni di chiamata.
È abbastanza facile combinare il codice scritto in C e C ++, poiché seguono molte delle stesse convenzioni e usano le stesse rappresentazioni di tipi. È un po 'meno facile combinare il codice scritto in C e Fortran 1 .
Poi ci sono combinazioni di codice Java in esecuzione in una VM che chiama codice C o C ++ nativo. Di nuovo, c'è un livello di interoperabilità (la Java Native Interface) che è richiesto.
I linguaggi di missaggio sono disponibili in diverse varietà, fondamentalmente in corso, fuori processo sulla stessa macchina e fuori processo attraverso la rete.
Il costo delle prestazioni nella miscelazione dei processi dipende dal fatto che sia necessario o meno il marshalling di argomenti complessi.
Il marshalling è fondamentalmente l'atto di copiare il contenuto di una struttura dati in una struttura dati che viene compresa dal lato in cui una funzione chiama.
Nel caso C / C ++ in-process, è gratuito, proprio come nel caso C / Objective-C, in quanto tutti questi linguaggi possono gestire direttamente strutture di dati C.
Nei casi di in-process C / Java e C / C #, le cose iniziano a diventare più complicate, poiché solo alcuni tipi specifici possono essere utilizzati attraverso il bordo senza marshalling.
Nei casi fuori processo, è necessario eseguire il marshalling di tutto, che è molto più lento anche su reti super veloci rispetto a localmente in memoria.
Il caso in-process C / C ++ a cui sembri essere maggiormente interessato è in realtà il fondamento di Windows e del kernel macOS. In entrambi i casi, le cose di livello molto basso vengono implementate in C, mentre il codice di livello superiore in C ++ utilizza direttamente le API C fornite dal codice di livello inferiore, senza alcuna penalizzazione delle prestazioni.
Ricorda che C ++ NON è un superset di C rigido, principalmente a causa di parole chiave. Finché non nominerai le tue funzioni "namespace", "template" o "auto", dovresti stare bene, anche se