c++ - que - Cómo resolver el error LNK2019: símbolo externo no resuelto-¿función?
link 2019 (10)
Recibo este error, pero no sé cómo solucionarlo.
Estoy usando Visual Studio 2013. Hice el nombre de la solución MyProjectTest Esta es la estructura de mi solución de prueba:
- function.h
#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H
int multiple(int x, int y);
#endif
-function.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 comencé a interesarme en la prueba unitaria, así que creé un proyecto de prueba:
Archivo> Nuevo> Proyecto ...> Instalado> Plantillas> Visual C ++> Prueba> Proyecto de prueba de unidad nativa>
Nombre: UnitTest1 Solución: Agregar 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 la carpeta de la solución:
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 recibo el error LNK2019: símbolo externo sin resolver. Sé que falta la implementación de la función múltiple . Intenté eliminar el archivo function.cpp y reemplacé la declaración con la definición, y se ejecutó. 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 bueno en inglés mucho. Gracias)
Acabo de descubrir que LNK2019
produce 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 fue muy críptico, pero reduje lo que faltaba al leer el error y proporcioné la definición fuera de la clase para aclarar esto.
Acabo de encontrarme con este problema en Visual Studio 2013. Aparentemente ahora, tener dos proyectos en la misma solución y configurar las dependencias no es suficiente. Necesita agregar una referencia de proyecto entre ellos. Para hacer eso:
- Haga clic derecho en el proyecto en la solución de explorar
- Haga clic en Agregar => Referencias ...
- Haga clic en el botón Agregar nueva referencia
- Marque las casillas de los proyectos de los que se basa este proyecto
- Haga clic en Aceptar
Como quiero que mi proyecto se compile en un EXE independiente, vinculé el proyecto UnitTest al archivo function.obj generado desde el function.cpp y funciona. Haga clic derecho en el proyecto ''UnitTest1''> Propiedades de configuración> Enlazador> Entrada> Dependencias Adicionales> agregue ".. / MyProjectTest / Debug / function.obj"
En Visual Studio 2017, si desea probar miembros públicos, simplemente coloque su proyecto real y proyecto de prueba en la misma solución, y agregue una referencia a su proyecto real en el proyecto de prueba.
Consulte C ++ Unit Testing en Visual Studio desde el blog de MSDN para obtener más detalles. También puede verificar las pruebas de unidad de escritura para C / C ++ en Visual Studio , así como Usar el Marco de prueba de unidad de Microsoft para C ++ en Visual Studio , el último es si necesita probar miembros no públicos y necesita poner las pruebas en el mismo proyecto como tu código real
Tenga en cuenta que las cosas que desea probar deberán exportarse usando __declspec(dllexport)
. Consulte Exportar desde una DLL usando __declspec (dllexport) para obtener más detalles.
En el árbol de soluciones de Visual Studio, haga clic con el botón derecho en el proyecto ''UnitTest1'' y luego agregue -> elemento existente -> elija el archivo ../MyProjectTest/function.cpp
Esto me pasó a mí, así que pensé que podría compartir mi solución, tan simple como era:
Compruebe el conjunto de caracteres de ambos proyectos en Propiedades de configuración -> General -> Conjunto de caracteres
Mi proyecto UnitTest usaba el conjunto de caracteres predeterminado Multi-Byte mientras que mis libs estaban en Unicode .
Mi función era usar un TCHAR como parámetro. Como resultado, en mi lib, mi TCHAR se transformó en WCHAR, pero fue un char * en mi UnitTest: el símbolo era diferente porque los parámetros en realidad no eran los mismos al final.
Otra forma de obtener este error de vinculador (como yo) es exportar una instancia de una clase desde un dll pero no haber declarado esa clase como importación / exportación.
#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 aunque principalmente estaba exportando solo una instancia de la clase Libro llamada book
anterior, tuve que declarar la clase Book
como clase de exportación / importación y, de lo contrario, llamar a book.WordCount()
en el otro dll estaba causando un error de enlace.
Para mí funciona, si agrego esta línea abajo en .vcxproj
en el archivo del itemGroup
cpp, que está conectado al archivo de encabezado.
<ClCompile Include="file.cpp" />
Resultó que estaba usando archivos .c con archivos .cpp. renombrar .c a .cpp resolvió mi problema.
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 breve 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 enlaces.
Dado que las pruebas de su unidad están en un proyecto diferente, asumo que su intención es hacer de ese proyecto un programa independiente de pruebas de unidades. Con las funciones que está probando ubicadas en otro proyecto, es posible construir ese proyecto en una biblioteca enlazada 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, preferiré las bibliotecas estáticas.
Puede convertir su primer programa en una biblioteca estática cambiándolo en las propiedades del proyecto. Debería haber una opción en la pestaña General donde el proyecto está configurado para compilar a un ejecutable ( .exe
). Puede cambiar esto a .lib
. El archivo .lib
se compilará en el mismo lugar que el .exe
.
En su proyecto UnitTest1
, puede ir a sus propiedades, y debajo de la pestaña Linker en la categoría Additional Library Directories, agregue la ruta a la cual MyProjectTest
construye. Luego, para las Dependencias Adicionales en la pestaña Enlazador - Entrada, agregue el nombre de su biblioteca estática, muy probablemente MyProjectTest.lib
.
Eso debería permitir que tu proyecto se 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.