euMesmo2 0 Denunciar post Postado Janeiro 2, 2012 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
Renato Utsch 24 Denunciar post Postado Janeiro 2, 2012 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