Eu tenho uma biblioteca C ++ que oferece várias classes para gerenciamento de dados. Eu tenho o código-fonte da biblioteca.
Quero estender a API C ++ para oferecer suporte a chamadas de função C para que a biblioteca possa ser usada com código C e código C ++ ao mesmo tempo.
Estou usando a cadeia de ferramentas GNU (gcc, glibc, etc), portanto, o suporte a linguagem e arquitetura não é um problema.
Há alguma razão pela qual isso não seja tecnicamente possível?
Há alguma pegadinha que eu preciso tomar cuidado?
Existem recursos, código de exemplo e / ou documentação disponível sobre isso?
Algumas outras coisas que descobri:
- Use o seguinte para envolver seus cabeçalhos C ++ que precisam ser usados pelo código C.
#ifdef __cplusplus
extern "C" {
#endif
//
// Code goes here ...
//
#ifdef __cplusplus
} // extern "C"
#endif
- Mantenha as interfaces C ++ "reais" em arquivos de cabeçalho separados que não estão incluídos em C. Pense no princípio PIMPL aqui. Usar
#ifndef __cplusplus #error
coisas ajuda aqui a detectar qualquer loucura. - Cuidado com os identificadores C ++ como nomes no código C
- Enums variando em tamanho entre compiladores C e C ++. Provavelmente não é um problema se você estiver usando a cadeia de ferramentas GNU, mas ainda assim, tome cuidado.
Para structs, siga a seguinte forma para que C não se confunda.
typedef struct X { ... } X
Em seguida, use ponteiros para passar objetos C ++, eles apenas precisam ser declarados em C como struct X, onde X é o objeto C ++.
Tudo isso é cortesia de um amigo que é um mago em C ++.
Respostas:
Sim, isso é certamente possível. Você precisará escrever uma camada de interface em C ++ que declare funções com
extern "C"
:Então, você chamará
foo()
de seu módulo C, que passará a chamada para arealFoo()
função que é implementada em C ++.Se você precisar expor uma classe C ++ completa com membros de dados e métodos, talvez precise fazer mais trabalho do que este exemplo de função simples.
fonte
extern "C"
ser colocado apenas em declarações (e não em definições)? Porque você mencionou "a camada que declara funções", mas seu código de amostra também é uma definição. Em outras palavras, devemos colocá-lo em arquivos de cabeçalho ou arquivos de origem? (Ou ambos?)extern "C"
lá. Seu compilador dirá se você também deve colocá-lo na definição.C ++ FAQ Lite: "Como misturar códigos C e C ++" .
Algumas pegadinhas são descritas em respostas a estas perguntas:
fonte
Principal pegadinha: as exceções não podem ser capturadas em C. Se houver a possibilidade de uma exceção surgir no código C ++, escreva seu código C ou seus wrappers C ++ com muito cuidado. Por outro lado, mecanismos semelhantes a exceções (isto é, salto longo) no código C (como encontrados em várias linguagens de script) não são necessários para invocar destruidores para objetos C ++ na pilha.
fonte
você pode misturar código C / C ++. Se sua função main () estiver em C ++, então você só precisa ter certeza de que suas funções c estão declaradas
Se o seu principal for C, provavelmente você está OK, exceto para as variáveis estáticas. Quaisquer construtores com suas variáveis estáticas devem ser chamados antes do início de main (). Isso não acontecerá se C for seu principal. Se você tiver muitas variáveis estáticas, a melhor coisa a fazer é substituir as variáveis estáticas por singletons.
fonte