Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

euMesmo2

Problemas ao mesclar c e c++

Recommended Posts

Bom, em meu projeto tennho os seguintes arquivos:

"animator.c":

...
int startAnimator(float delayTime, void(*func)(void*), void* funcArg) {
   ...
}
...

 

"animator.h":

   int startAnimator(float delayTime, void(*func)(void*), void* funcArg);

 

"main.cpp":

void cycle(void* arg){
   ...
}

int main(){
   startAnimator(500, cycle, NULL);
}

 

O problema é que quando tento compilalo, obtenho o seguinte erro:

undefined reference to `startAnimator(float, void (*)(void*), void*)'

Mas o arquivo animator.c funcionava perfeitamente em um outro projeto que desenvolvi, mas este era em c.

Alguem sabe como resolver?

 

OBS:

minha TOOLCHAIN:

Cross GCC Compiler

Cross G++ Compiler

Cross G++ Linker

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiro, se vai compilar arquivos .c, utilize o gcc para compilar ele, e não o g++, ficando algo como a seguinte linha de compilação:

 

gcc -o animator.o -c animator.c
g++ -o main.o -c main.cpp
ld -o animator main.o animator.o // OU g++ -o animator main.o animator.o

OBS: Recomendo que adicione as linhas -Wall -Wextra -Werror ao seu código, pois isso ajuda a detectar MUITOS problemas em que o código compila mas não compilaria com essas 3 switches. Eu uma vez esqueci de adicioná-las e acabei levando 40min para debuggar e descobrir o problema no código, e fiquei frustrado porque essas 3 linhas não me deixam compilar o programa com o tipo de erro bobo que cometi...

 

Sugiro que passe isso para uma makefile, ou, melhor ainda utilize o cmake... é como as autotools só que muito mais fácil de usar e que funciona em mais sistemas operacionais (como, por exemplo, no windows). Olha que bonitinho o código que vai traduzir o que foi escrito acima (a parte de compilação):

 

# Esse código deve ser colocado em um CMakeLists.txt. Presume-se
# que os arquivos estão na pasta em que o CMakeLists.txt está.
# Para compilar, utilize os seguintes
# comandos (a partir da pasta onde está o CMakeLists.txt):
#
# cd ..
# mkdir build
# cd build
# cmake ../${PASTA_DA_SOURCE}
# make
#
# OU
#
# cmake .
# make
#
# Em que ${PASTA_DA_SOURCE} é o nome da pasta onde está a source.
#
cmake_minimum_required( VERSION 2.8 ) # A versão mínima do CMake requerida por 
                                     # esse script é a 2.8.
project( ANIMATOR C C++ ) # Nome do projeto, que é escrito em C e C++.

# Se quer adicionar -Wall -Wextra -Werror, só descomente a seguinte linha:
# Mas lembre-se que isso vai fazer com que o programa fique dependente do compilador
# do GCC, não funcionará em outros.
#add_definitions( -Wall -Wextra -Werror )

# A variável ${CMAKE_SOURCE_DIR} contém o caminho completo até a pasta da source.
add_executable( ANIMATOR "${CMAKE_SOURCE_DIR}/animator.c"
                        "${CMAKE_SOURCE_DIR}/main.cpp" )

 

Esse programa tem apenas 3 linhas, e compila seu código sem torná-lo dependente de um compilador. Você pode ver como mudar o compilador digitando isso na linha de comando:

 

cmake --help

 

Você pode compilar com o GCC, MinGW, Cygwin Visual Studio, Borland C++, Eclipse, Intel C++ Compiler, entre MUITOS outros...

 

-------------

 

Mas então, para esse código funcionar direito, você deve especificar no animator.h que, caso incluído por um programa em C++, que o código fonte do header é em C. Como fazer isso?

 

Primeiro, adicione o extern "C" { e } no código:

 

--- animator.h [VERSION 2]

extern "C" {

int startAnimator(float delayTime, void(*func)(void*), void* funcArg);

}

 

Isso vai dizer ao compilador que o código não é em C++, é em C. Mas isso vai fazer com que o header não funcione em programas escritos em C, só em programas escritos em C++, pois a C não tem essa keyword. Como resolver? Simples, utilize compilação condicional:

 

--- animator.h [VERSION 3]

#ifdef __cplusplus
extern "C" {
#endif

int startAnimator(float delayTime, void(*func)(void*), void* funcArg);

#ifdef __cplusplus
}
#endif

 

Esse's #ifdef's e #endif's farão que a extern "C" { e } só sejam incluídos caso o programa for em C++, se for em C não serão. Fazer isso é até boa prática.

 

 

Teste assim e diga se deu certo ^^

 

 

Abraços :D

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.