Pregunta

Acabamos de tener una experiencia interesante al tratar de vincular un conjunto de código compilado con Visual Studio Express 2008 con un .lib compilado con Visual Studio 2003. Todo en C ++. Para ser precisos, que era el SystemC 2.2.0 kernel que se compiló en VS2003 en un .lib, y un modelo SystemC que fue compilado en VS2008.

Cuando se enlaza, seguimos recibiendo el error que algunos símbolos del archivo SystemC.lib (es decir, compilado en VS2003) no fueron encontrados durante la vinculación. El error conseguimos conseguir era esto (en algunas variantes):

SystemC.lib(sc_port.obj) : error LNK2001: unresolved external symbol "public: vo
id __thiscall std::_String_base::_Xran(void)const " (?_Xran@_String_base@std@@QB
EXXZ)

Digging desde varios clientes potenciales, resultó que la función de la Lib esperaba encontrar era la siguiente:

Undecoration of :- "?_Xran@_String_base@std@@QBEXXZ"
is :- "public: void __thiscall std::_String_base::_Xran(void)const "

Mientras que el archivo de biblioteca que VS2008 estaba tratando de enlazar con (libcpmt.lib) utiliza una convención de llamada diferentes:

Undecoration of :- "?_Xran@_String_base@std@@SAXXZ"
is :- "public: static void __cdecl std::_String_base::_Xran(void)"

He intentado averiguar por qué ocurrió esta incompatibilidad, pero al final me di por vencido, recompilado el mismo proyecto de Visual Studio exacta en VS2008, y se utiliza SystemC.lib que en lugar de la de VS2003. Ahora, las cosas funcionaron a la perfección.

Así que la pregunta fundamental aquí es: ¿qué ha cambiado desde VS2003 a VS2008 que haría que algunas funciones para cambiar sus convenciones de llamada? ¿Y hay alguna bandera de magia para darle al enlazador en VS2008 usar alguna otra biblioteca en la que las funciones tienen la misma convención de llamada como en el VS2003 compilar?

Actualizar, resumen de las respuestas hasta el momento : Es muy probable que Microsoft cambia el C ++ (no en C, C ++ solo) ABI de una versión principal de Visual Studio para la próxima. También puede haber otros cambios en las bibliotecas que no sea compatible. El mejor consejo es volver a compilar el .lib para cada versión de VS. Esencialmente, sólo se enviará en la fuente a los usuarios y hacer que se compilan de forma local utilizando cualquier versión de VS, por casualidad, se han instalado.

La cuestión básica fue descubierto por el uso de la asistencia en:

Tenga en cuenta que estas preguntas no respondieron a este problema:

¿Fue útil?

Solución

No hay un estándar para el C ++ ABI. Lo que significa que todo el compilador de C ++ podría manejar una ABI diferente de uno a otro, y que incluye la versión diferente del mismo compilador. Usted podría tener el mismo problema con 2 versión principal diferente de gcc. Tal modificación podría suceder cuando encuentran una manera de mejorar la vinculación de paso.

Pero ABI implica mucho más que eso. Por ejemplo, la forma en vtable se almacena y maneja detrás de la campana por el código generado por el compilador. Si cambia, sus objetos y su código generados en 2008 no serán compatibles con la biblioteca esperando la forma en que se lleva a cabo en el año 2003.

En este punto se podría entender por qué bibliotecas de C ++ o bien se entregan con su código fuente o compilado enviados en muchos arquitectura diferente y compiladores.

Por lo general, cuando se escribe una biblioteca, con el fin de evitar este tipo de problemas, a desarrollar en C langage, no C ++. Como C viene con un ABI estándar, usted es capaz de compilar con un compilador y luego enlazar esa biblioteca con cualquier compilador C wich respeto que C estándar ABI. Por ejemplo, la cadena de caracteres manera se implementa es estándar y probablemente nunca mover (la infame cadena terminada en nulo). Si bien los cambios de implementación std :: string de un lanzamiento importante GCC para el otro (sólo echar un vistazo en la clase de basic_string /usr/include/c++/x.x/bits/basic_string archivos)

Otros consejos

Por lo que yo sé que estos problemas ocurren debido a la biblioteca CRT, que cambian con las versiones principales y no se debe mezclar los tipos de CRT (multi-hilo, depuración, liberación, estática, dinámica, etc.).

Por lo general, se pueden minimizar mediante la vinculación dinámica con CRT, tuve éxito la reutilización de las bibliotecas en VS2003 VS2005 pero es molesto, es mejor simplemente recompilar todo el asunto. A veces se puede salir mediante el uso de la bandera / NODEFAULTLIB compilador para evitar la vinculación con una determinada biblioteca CRT que está causando problemas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top