Cómo resolver el error LNK2019: función de símbolo externo sin resolver?


Recibo este error, pero no se como solucionarlo.

Estoy usando Visual Studio 2013. Hice el nombre de la solución MyProjectTest Esta es la estructura de mi solución de prueba:

Estructura

-función.h

#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H

int multiple(int x, int y);
#endif

-función.cpp

#include "function.h"

int multiple(int x, int y){
    return x*y;
}

-main.cpp

#include <iostream>
#include <cstdlib>
#include "function.h"
using namespace std;

int main(){
    int a, b;
    cin >> a >> b;
    cout << multiple(a, b) << endl;

    system("pause");
    return 0;
}

Soy un principiante; este es un programa simple y se ejecuta sin error. Leí en Internet y me interesé en la prueba unitaria, así que creé una prueba proyecto:

Archivo > Nuevo > Proyecto... > Instalado > Plantillas > Visual C++ > Prueba > Proyecto de Prueba de Unidad Nativa >

Nombre: UnitTest1 Solución: Añadir a la solución Luego, la ubicación cambió automáticamente a la ruta de la solución abierta actual Esta es la estructura de carpetas de la solución:

Estructura de carpetas

Solo edité el archivo unittest1.cpp:

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../MyProjectTest/function.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(UnitTest1)
    {
    public:

        TEST_METHOD(TestEqual)
        {

            Assert::AreEqual(multiple(2, 3), 6);
            // TODO: Your test code here
        }

    };
}

Pero obtengo el error LNK2019: símbolo externo sin resolver. Sé que la implementación de falta la función múltiple. Intenté borrar la función.cpp file y yo reemplazamos la declaración con la definición, y se ejecuta. Pero no se recomienda escribir tanto la declaración como la definición en el mismo archivo. ¿Cómo puedo solucionar este error sin hacer eso? Debo reemplazar con #include "../MyProjectTest/function.cpp" en el archivo unittest.cpp? (No soy muy bueno en inglés. Gracias)

Author: georges619, 2013-11-10

10 answers

Una opción sería incluir function.cpp en su proyecto UnitTest1, pero esa puede no ser la estructura de solución más ideal. La respuesta corta a su problema es que al construir su proyecto UnitTest1, el compilador y el enlazador no tienen idea de que function.cpp existe, y tampoco tienen nada que enlazar que contenga una definición de multiple. Una forma de solucionar esto es haciendo uso de bibliotecas de enlace.

Dado que sus pruebas unitarias están en un proyecto diferente, asumo que su intención es hacer que ese proyecto sea un programa independiente de pruebas unitarias. Con las funciones que está probando ubicadas en otro proyecto, es posible construir ese proyecto en una biblioteca vinculada dinámica o estáticamente. Las bibliotecas estáticas están vinculadas a otros programas en tiempo de compilación, y tienen la extensión .lib, y las bibliotecas dinámicas están vinculadas en tiempo de ejecución, y tienen la extensión .dll. Para mi respuesta prefiero bibliotecas estáticas.

Puedes convertir tu primer programa en una biblioteca estática cambiándola en los proyectos propiedad. Debería haber una opción en la pestaña General donde el proyecto esté configurado para construir un ejecutable (.exe). Puede cambiar esto a .lib. El archivo .lib se construirá en el mismo lugar que el .exe.

En su proyecto UnitTest1, puede ir a sus propiedades, y en la pestaña Enlazador en la categoría Directorios de Bibliotecas adicionales, agregue la ruta a la que se construye MyProjectTest. Luego, para Dependencias Adicionales en la pestaña Enlazador - Entrada, agregue el nombre de su biblioteca estática, la mayoría probablemente MyProjectTest.lib.

Eso debería permitir que su proyecto construya. Tenga en cuenta que al hacer esto, MyProjectTest no será un programa ejecutable independiente a menos que cambie sus propiedades de compilación según sea necesario, lo que sería menos que ideal.

 56
Author: kevintodisco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-10 05:47:48

En el árbol de soluciones de Visual Studio, haga clic derecho en el proyecto 'UnitTest1' y luego Agregue -> Elemento existente -> elija el archivo ../MyProjectTest / function.cpp

 31
Author: Niyaz Ivanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-10 05:09:20

Dado que quiero que mi proyecto se compile a un EXE independiente, vinculé el proyecto UnitTest a la función.archivo obj generado a partir de la función.cpp y funciona. Haga clic derecho en el proyecto' UnitTest1 '> Propiedades de configuración > Enlazador > Entrada > Dependencias adicionales > agregar"..\MyProjectTest \ Debug \ function.obj "

 11
Author: harrygg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-05 13:17:56

Resultó que estaba usando .c archivos .archivos cpp. cambio de nombre .c a .cpp resolvió mi problema.

 8
Author: cahit beyaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-04 19:39:08

Acabo de encontrarme con este problema en Visual Studio 2013. Aparentemente ahora, tener dos proyectos en la misma solución y establecer las dependencias no es suficiente. Es necesario añadir una referencia de proyecto entre ellos. Para hacer eso:

  1. Haga clic derecho en el proyecto en la solución explorar
  2. Haga clic en Agregar = > Referencias...
  3. Haga clic en el botón Agregar nueva referencia
  4. Marque las casillas para los proyectos en los que se basa este proyecto
  5. Haga clic en Aceptar
 7
Author: Kevin Dill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-22 21:07:19

Otra forma de obtener este error de enlazador (como lo hice yo) es si está exportando una instancia de una clase desde una dll pero no ha declarado esa clase como import/export.

 #ifdef  MYDLL_EXPORTS 
    #define DLLEXPORT __declspec(dllexport)  
 #else
    #define DLLEXPORT __declspec(dllimport)  
 #endif

class DLLEXPORT Book // <--- this class must also be declared as export/import
{
public: 
    Book();
    ~Book();
    int WordCount();
};

DLLEXPORT extern Book book; // <-- This is what I really wanted, to export book object

Así que a pesar de que principalmente estaba exportando solo una instancia de la clase Book llamada book anterior, tuve que declarar la clase Book como clase export/import y, de lo contrario, llamar a book.WordCount() en la otra dll estaba causando un error de enlace.

 2
Author: zar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-10 16:46:16

Acabo de descubrir que LNK2019 ocurre durante la compilación en Visual Studio 2015 si se olvida de proporcionar una definición para una función declarada dentro de una clase.

El error del enlazador era muy críptico, pero reduje lo que faltaba leyendo el error y proporcioné la definición fuera de la clase para aclarar esto.

 1
Author: Mushy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-10 18:10:41

Para mí funciona, si agrego esta línea a continuación en .vcxproj en el archivo cpp itemGroup, que está conectado al archivo de encabezado.

<ClCompile Include="file.cpp" />
 0
Author: Nejc Galof,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-29 13:23:16

Esto me sucedió así que pensé que podría compartir mi solución, tan simple como era:

Comprobar el Conjunto de Caracteres de ambos proyectos en Propiedades de Configuración -> General -> Conjunto de Caracteres

Mi proyecto UnitTest estaba usando el Conjunto de caracteres predeterminado Multi-Byte mientras que mis libs estaban en Unicode.
Mi función estaba usando un TCHAR como parámetro. Como resultado en mi lib mi TCHAR fue transformado en un WCHAR pero era un char* en mi UnitTest: el símbolo era diferente porque los parámetros no eran realmente los mismos al final.

 0
Author: Enyx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-28 15:44:17

En Visual Studio 2017 si desea probar miembros públicos, simplemente coloque su proyecto real y el proyecto de prueba en la misma solución, y agregue una referencia a su proyecto real en el proyecto de prueba.

Ver Pruebas unitarias de C++ en Visual Studio desde el blog de MSDN para más detalles. También puede comprobar Escribir pruebas unitarias para C / C++ en Visual Studio , así como Usar el Marco de pruebas Unitarias de Microsoft para C++ en Visual Studio , siendo este último si necesita probar no miembros públicos y necesitan poner las pruebas en el mismo proyecto que su código real.

Tenga en cuenta que las cosas que desea probar deberán exportarse utilizando __declspec(dllexport). Ver Exportar desde una DLL Usando __declspec(dllexport) para más detalles.

 0
Author: user276648,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-25 02:29:17