studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones c function linker-errors undefined-reference

para - manual de programacion android pdf



C error: referencia indefinida a la función, pero está definido (4)

¿Cómo estás compilando y vinculando? Deberá especificar ambos archivos, algo como:

gcc testpoint.c point.c

... para que sepa unir las funciones de ambas juntas. Sin embargo, con el código tal como está escrito en este momento, se encontrará con el problema opuesto: múltiples definiciones de main . Necesitarás / querrás eliminar uno (indudablemente el que está en el punto.c).

Editar: en un programa más grande, normalmente compila y vincula por separado para evitar volver a compilar todo lo que no ha cambiado. Normalmente se especifica lo que se debe hacer a través de un archivo MAKE y se usa make para hacer el trabajo. En este caso, tendrías algo como esto:

OBJS=testpoint.o point.o testpoint.exe: $(OBJS) gcc $(OJBS)

El primero es solo una macro para los nombres de los archivos objeto. Obtiene se expande con $(OBJS) . La segunda es una regla para decir a make 1) que el ejecutable depende de los archivos del objeto, y 2) diciéndole cómo crear el ejecutable cuando / si está desactualizado en comparación con un archivo objeto.

La mayoría de las versiones de make (incluida la de MinGW, estoy bastante seguro) tienen una "regla implícita" incorporada para indicarles cómo crear un archivo de objeto a partir de un archivo fuente en C. Por lo general, se ve más o menos así:

.c.o: $(CC) -c $(CFLAGS) $<

Esto supone que el nombre del compilador de C se encuentra en una macro llamada CC (implícitamente definida como CC=gcc ) y le permite especificar cualquier indicador que le interese en una macro denominada CFLAGS (por ejemplo, CFLAGS=-O3 para activar la optimización) y $< es una macro especial que se expande al nombre del archivo fuente.

Normalmente lo almacena en un archivo llamado Makefile , y para construir su programa, simplemente escriba make en la línea de comando. Busca implícitamente un archivo llamado Makefile y ejecuta las reglas que contiene.

El buen punto de esto es que make busca automáticamente las marcas de tiempo en los archivos, por lo que solo volverá a compilar los archivos que han cambiado desde la última vez que los compiló (es decir, los archivos en los que el archivo ".c" tiene más sello de tiempo reciente que el archivo ".o" coincidente).

También tenga en cuenta que 1) hay muchas variaciones en cómo usar make cuando se trata de proyectos grandes, y 2) también hay muchas alternativas para hacer. Solo he llegado al mínimo de puntos altos aquí.

Solo un programa simple, pero sigo recibiendo este error de compilación. Estoy usando MinGW para el compilador.

Aquí está el archivo de encabezado, point.h :

//type for a Cartesian point typedef struct { double x; double y; } Point; Point create(double x, double y); Point midpoint(Point p, Point q);

Y aquí está el punto.c :

//This is the implementation of the point type #include "point.h" int main() { return 0; } Point create(double x, double y) { Point p; p.x = x; p.y = y; return p; } Point midpoint(Point p, Point q) { Point mid; mid.x = (p.x + q.x) / 2; mid.y = (p.y + q.y) / 2; return mid; }

Y aquí es donde entra el problema del compilador. Sigo recibiendo:

testpoint.c: referencia indefinida a ''crear (doble x, doble y)''

Mientras está definido en el punto.c.

Este es un archivo separado llamado testpoint.c :

#include "point.h" #include <assert.h> #include <stdio.h> int main() { double x = 1; double y = 1; Point p = create(x, y); assert(p.x == 1); return 0; }

No sé cuál podría ser el problema.


Agregue la palabra clave "extern" a las definiciones de función en point.h


Creo que el problema es que cuando intentas compilar testpoint.c, incluye point.h pero no sabe sobre point.c. Como point.c tiene la definición de create , no tener point.c hará que la compilación falle.

No estoy familiarizado con MinGW, pero necesita decirle al compilador que busque el punto.c. Por ejemplo, con gcc puedes hacer esto:

gcc point.c testpoint.c

Por supuesto, como others han señalado, también debe eliminar una de sus funciones main , ya que solo puede tener una.


Tuve este problema recientemente. En mi caso, tenía mi IDE configurado para elegir qué compilador (C o C ++) usar en cada archivo según su extensión, e intentaba llamar a una función C (es decir, desde un archivo .c ) desde el código C ++.

El archivo .h para la función C no estaba envuelto en este tipo de guardia:

#ifdef __cplusplus extern "C" { #endif // all of your legacy C code here #ifdef __cplusplus } #endif

Podría haber agregado eso, pero no quería modificarlo, así que simplemente lo incluí en mi archivo C ++ así:

extern "C" { #include "legacy_C_header.h" }

(Sombrero propina a UncaAlby por su explicación clara del efecto de la "C" externa ).