Tenho uma função C que gostaria de chamar de C ++. Não pude usar o extern "C" void foo()
tipo de abordagem " " porque a função C falhou ao ser compilada usando g ++. Mas compila bem usando o gcc. Alguma idéia de como chamar a função de C ++?
87
g++
mensagens de errovoid valid_in_C_but_not_in_CPlusPlus(size_t size) { char variable_length_array[size]; }
void f(void *pv) { int *pi = pv; *pi = 42; }
^^Respostas:
Compile o código C assim:
Então o código C ++ como este:
Em seguida, vincule-os, com o vinculador C ++:
Você também precisa informar ao compilador C ++ que um cabeçalho C está chegando ao incluir a declaração da função C. Então
othercode.cpp
começa com:somecode.h
deve conter algo como:(Eu usei gcc neste exemplo, mas o princípio é o mesmo para qualquer compilador. Construa separadamente como C e C ++, respectivamente, e então vincule-os.)
fonte
extern "C"
no cabeçalho com#ifdef __cplusplus
.Deixe-me reunir os fragmentos de outras respostas e comentários, para dar um exemplo com códigos C e C ++ separados de forma clara:
A parte C:
foo.h :
foo.c
Compile isso com
gcc -c -o foo.o foo.c
.A parte C ++:
bar.cpp
Compile isso com
g++ -c -o bar.o bar.cpp
E então conecte tudo junto:
Justificativa: O código C deve ser um código C simples, sem
#ifdef
"talvez algum dia eu chame isso de outra linguagem". Se algum programador C ++ chama suas funções C, é o seu problema de como fazer isso, não o seu. E se você é o programador C ++, então o cabeçalho C pode não ser seu e você não deve alterá-lo, então o tratamento de nomes de função não fragmentados (ou seja, oextern "C"
) pertence ao seu código C ++.Você pode, é claro, escrever um cabeçalho C ++ conveniente que não faz nada, exceto envolver o cabeçalho C em um
extern "C"
declaração.fonte
Concordo com a resposta do Prof. Falken , mas após o comentário de Arne Mertz quero dar um exemplo completo (a parte mais importante é o
#ifdef __cplusplus
):somecode.h
somecode.c
othercode.hpp
othercode.cpp
Então você segue as instruções do Prof. Falken para compilar e vincular.
Isso funciona porque, ao compilar com
gcc
, a macro__cplusplus
não está definida, então o cabeçalhosomecode.h
incluídosomecode.c
fica assim após o pré-processamento:e ao compilar com
g++
, then__cplusplus
é definido e, portanto, o cabeçalho incluídoothercode.cpp
agora é assim:fonte
#ifdef __cplusplus
código C. O código C é o nível inferior e não deve se preocupar se algum dia poderá ser chamado a partir do código C ++. Imo que#ifdef
tem seu uso apenas em código C ++ se você deseja fornecer um cabeçalho de ligação C para uma biblioteca escrita em C ++, e não o contrário.Essa resposta é inspirada por um caso em que o raciocínio de Arne estava correto. Um fornecedor escreveu uma biblioteca que antes suportava C e C ++; no entanto, a versão mais recente suportava apenas C. As seguintes diretivas vestigiais deixadas no código eram enganosas:
Isso me custou várias horas tentando compilar em C ++. Simplesmente chamar C de C ++ foi muito mais fácil.
A convenção ifdef __cplusplus viola o princípio de responsabilidade única. Um código que usa essa convenção tenta fazer duas coisas ao mesmo tempo:
É como tentar escrever em inglês americano e britânico ao mesmo tempo. Isso está jogando desnecessariamente uma #ifdef __thequeensenglish spanner #elif __yankeeenglish wrench #else uma ferramenta inútil que torna o código mais difícil de ler #endif no código.
Para código simples e pequenas bibliotecas, a convenção ifdef __cplusplus pode funcionar; entretanto, para bibliotecas complexas, é melhor escolher um idioma ou outro e ficar com ele. O suporte a um dos idiomas exigirá menos manutenção do que tentar oferecer o suporte a ambos.
Este é um registro das modificações que fiz no código de Arne para compilá-lo no Ubuntu Linux.
foo.h :
foo.c
bar.cpp
Makefile
fonte