Error de las herramientas del vinculador LNK2019
Actualización: noviembre 2007
Mensaje de error
símbolo externo 'símbolo' sin resolver al que se hace referencia en la función 'función'
unresolved external symbol 'symbol' referenced in function 'function'
Se halló un símbolo externo no definido (symbol) en function. Para resolver este error, indique una definición de símbolo o quite el código que hace referencia a él. Para obtener más información, vea:
El ejemplo siguiente genera el error LNK2019:
// LNK2019.cpp
// LNK2019 expected
extern char B[100]; // B is not in avilable to the linker
int main() {
B[0] = ' ';
}
El error LNK2019 también se puede producir cuando se declara un miembro de datos estático, pero no se define. El ejemplo siguiente genera el error LNK2019:
// LNK2019b.cpp
// LNK2019 expected
struct C {
static int s;
};
// Uncomment the following line to resolve.
// int C::s;
int main() {
C c;
C::s = 1;
}
Considere el ejemplo siguiente:
// LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
i++;
g();
}
int main() {}
Si i y g no están definidas en uno de los archivos incluidos en la generación, el vinculador emitirá el error LNK2019. Estas definiciones pueden agregarse incluyendo el archivo de código fuente que contiene las definiciones como parte de la compilación. Como alternativa, se pueden pasar archivos .obj o .lib que contengan las definiciones para el vinculador.
En los proyectos de C++ procedentes de versiones anteriores que se han actualizado a la versión actual, si se definió __UNICODE y el punto de entrada era WinMain, será necesario cambiar el nombre de la función del punto de entrada a _tWinMain o wWinMain.
Problemas comunes que causan LNK2019:
La declaración del símbolo contiene un error de escritura, de manera que no es el mismo que la definición del símbolo.
Se utilizó una función, pero el tipo o número de parámetros no coincide con la definición de la función.
La convención de llamada (__cdecl, __stdcall, o __fastcall) difiere en el uso de la declaración de función y la definición de función.
Las definiciones de símbolo se encuentran en un archivo que se compiló como un programa de C, mientras que los símbolos se declaran en un archivo de C++ sin modificador extern "C". En ese caso, modifique la declaración, por ejemplo, en lugar de:
extern int i; extern void g();
utilice:
extern "C" int i; extern "C" void g();
Igualmente, si define un símbolo en un archivo de C++ que se usará en otro programa de C, use extern "C" en la definición.
Un símbolo está definido como static y después se hace referencia a él fuera del archivo. En C++, a diferencia de C, las constantes globales tienen vinculación static. Para resolver esta limitación, se puede incluir las inicializaciones const en un archivo de encabezado e incluirlo en los archivos .cpp, o hacer la variable no constante y utilizar una referencia constante para obtener acceso a ella.
Un miembro static de una clase no está definido. Por ejemplo, la variable miembro si de la declaración de clase siguiente debe definirse por separado:
// LNK2019d.cpp #include <stdio.h> struct X { static int si; }; // int X::si = 0; // uncomment this line to resolve int main() { X *px = new X[2]; printf_s("\n%d",px[0].si); // LNK2019 }
El ejemplo siguiente genera el error LNK2019 en un operador definido por el usuario.
// LNK2019e.cpp
// compile with: /EHsc
// LNK2019 expected
#include <iostream>
using namespace std;
template<class T> class
Test {
friend ostream& operator<<(ostream&, Test&);
// Uncomment the following line to resolve.
// template<typename T> friend ostream& operator << (ostream&, Test<T>&);
};
template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
return os;
}
int main() {
Test<int> t;
cout << "Test: " << t << endl; // unresolved external
}
La opción del compilador /VERBOSE ayudará a ver a qué archivos hace referencia el vinculador. Las opciones /EXPORTS y /SYMBOLS de la herramienta DUMPBIN también pueden ayudar a ver qué símbolos están definidos en los archivos DLL y de objeto/biblioteca.
Microsoft Knowledge Base contiene más información sobre el error LNK2019; vea https://support.microsoft.com.
El error LNK2019 también puede producirse como resultado del trabajo de conformidad realizado para Visual Studio .NET 2003: especialización y friends de plantillas. En Visual Studio .NET 2003, una declaración de una función friend con el mismo nombre que una plantilla de función no hace referencia a esa plantilla a no ser que se hayan especificado explícitamente argumentos de plantilla en la declaración friend.
Si no se especifican argumentos de plantilla, la declaración friend declara una función que no es de plantilla.
Para obtener más información, vea Resumen de cambios importantes en tiempo de compilación.
Para que el código sea válido en las versiones Visual Studio .NET 2003 y Visual Studio .NET de Visual C++, especifique explícitamente la lista de argumentos de plantilla de la función friend.
// LNK2019f.cpp
// LNK2019 expected
template<class T>
void f(T) {}
template<class T>
struct S {
friend void f(T);
// try the folowing line instead
// friend void f<T>(T);
};
int main() {
S<int> s;
f(1); // unresolved external
}
El error LNK2019 también se puede producir como resultado del trabajo de conformidad efectuado en Visual C++ 2005; /Zc:wchar_t ahora estará activado de manera predeterminada. Es posible que no se hayan compilado todos los módulos con la misma configuración de /Zc:wchar_t, en cuyo caso, las referencias de tipos no se resolverían como tipos compatibles. Para resolverlo, asegúrese de que los tipos de todos los módulos sean compatibles, ya sea compilando con la configuración adecuada de /Zc:wchar_t (por ejemplo, utilizando /Zc:wchar_t- al generar módulos con el conjunto de herramientas de Visual C++ 2005 que estarán vinculados con módulos de versiones anteriores) o, si es posible, actualizando los tipos para hacerlos compatibles.
Las referencias explícitas a comsupp.lib, ya sea desde la directiva pragma comment o a través de la línea de comandos, se deben cambiar para utilizar comsuppw.lib o comsuppwd.lib, ya que /Zc:wchar_t ahora está activado de forma predeterminada. comsupp.lib todavía se debe utilizar cuando se compile con /Zc:wchar_t-.
Para obtener más información, vea Cambios importantes en el compilador de Visual C++ 2005 y /Zc:wchar_t (wchar_t es un tipo nativo).
El ejemplo siguiente crea una exportación que utiliza WCHAR, que se resuelve como wchar_t.
// LNK2019g.cpp
// compile with: /LD
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}
El ejemplo siguiente genera el error LNK2019:
// LNK2019h.cpp
// compile with: LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);
int main() {
func(0);
}
Para resolver este error, cambie short sin signo por wchar_t o WCHAR, o compile LNK2019g.cpp con /Zc:wchar_t-.
También puede obtener el error LNK2019 si está generando una aplicación de consola con /SUBSYSTEM:WINDOWS. El símbolo no resuelto será _WinMain@16. En este caso, simplemente establezca un vínculo con /SUBSYSTEM:CONSOLE.