Errores al vincular a protobuf 3 en MSVC 2013

Cloné la biblioteca de buffer de protocolo de github, ejecuté CMake-gui en ella (dejé todo por defecto, así que es la versión estática), solo libprotobuf (otro proyecto falló por alguna razón, error cmd.exe, podría tener algo que ver con pruebas, pero libprotobuf comstack bien).

Mi proyecto usa los encabezados generados con el archivo .proto que se encuentra en el github de la especificación de tiles del vector mapbox.

Cuando me enlace, primero tengo este error

Error 1 error C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' s:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility

Intenté desactivarlo con -D_SCL_SECURE_NO_WARNINGS en argumentos de línea de comando adicionales, pero luego tengo otros errores:

Error 1 error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in main.obj S:\eiogit3\misc-projs\mapload\mapload\libprotobufd.lib(common.obj)

Es una discrepancia de cómo la biblioteca de tiempo de ejecución de VStudio C (y C ++) es utilizada por su proyecto y por el proyecto libprotobuf . Déjame detallar:

Digamos que hay un código C El propósito de ese código es ejecutar. Que se puede lograr:

  • Directamente: incluye ese código en un proyecto de tipo de aplicación de VC , que generará un .exe
  • Indirectamente: incluye el código en un proyecto de tipo VC Library , que generará una biblioteca que solo podrá ejecutarse cuando se llame desde otro .exe (que llame a esa biblioteca). La biblioteca puede ser:
    • estático : todo el código C se comstackrá y almacenará en un archivo .lib . Necesitará ese archivo cuando use la biblioteca en otro proyecto (ya sea una aplicación o una biblioteca) – en el momento del enlace . Tenga en cuenta que todo el código necesario de su .lib se “copiará” en el otro proyecto
    • dynamic : ahora tendrá 2 archivos: un archivo .dll que contendrá el código comstackdo (y vinculado) y un .lib que contendrá “punteros” (si lo desea) al código en el archivo .dll . Al utilizar la biblioteca en otro proyecto, también necesitará el archivo .lib en el momento del enlace , pero ahora no contendrá el código, por lo que no se copiará en la otra biblioteca (la otra biblioteca será más pequeña), pero en tiempo de ejecución, la otra biblioteca necesitará el archivo .dll

Puede verificar [SO]: LNK2005 Error en CLR Windows Form (respuesta de @ CristiFati) para obtener detalles sobre cómo se transforma el código C en formato ejecutable. Además, Google está lleno de artículos sobre las diferencias entre bibliotecas estáticas y dinámicas, cuándo usar uno u otro, se puede encontrar un ejemplo en [SO]: cuándo usar bibliotecas dinámicas frente a estáticas .

Como suponía, la biblioteca C runtime (contiene el sistema subyacente que hace que el código C sea ​​capaz de ejecutarse; un ejemplo son las funciones de administración de memoria: malloc , free ) no hace excepción, es el equivalente de Ux : libc.a (estático o de archivo) ) vs. libc.so (objeto dynamic o compartido) – pero en VStudio es un poco más complicado:

  • El tiempo de ejecución de C estático reside en libcmt.lib
  • El tiempo de ejecución de C dynamic reside en msvcrt.lib que “apunta” a msvcrxxx.dll ( msvcr120.dll para VStudio 2k13 ). Para versiones más nuevas de VStudio (comenzando en 2015 ), la parte msvcr ha sido reemplazada por vcruntime (o al menos este es el punto de entrada, ya que se dividió en partes lógicas más pequeñas)

Notas :

  • Una ” d ” al final del nombre de la biblioteca ( msvcr d .lib ), significa que está comstackda con símbolos de depuración
  • La biblioteca de tiempo de ejecución C ++ se encuentra en la situación exacta; los nombres tienen un p adicional: libcpmt.lib , msvcprt.lib , msvcp120.dll

Ahora, las bibliotecas de tiempo de ejecución de C / C ++ no están incluidas en el proyecto como cualquier otra lib ( Propiedades del proyecto -> Enlazador -> Entrada -> Dependencias adicionales ), pero debido a su naturaleza (estática o dinámica) es necesaria en tiempo de comstackción, están configuradas desde: [MSDN]: / MD, / MT, / LD (Usar biblioteca de tiempo de ejecución) , donde hay 4 opciones disponibles:

  • Multi-threaded ( / MT )
  • Depuración multiproceso ( / MTd )
  • DLL de subprocesos múltiples ( / MD )
  • DLL de depuración de múltiples subprocesos ( / MDd )

Obviamente, los que contienen “Debug” son cuando se construye para la configuración de depuración , mientras que los otros para la versión ; el punto clave es que los que tienen DLL están utilizando la versión de tiempo de ejecución dynamic , mientras que los otros tienen la versión estática .

Volver a su error : el enlazador se queja de que main.obj (parte de su proyecto) tiene MDd_DynamicDebug (vinculando con la versión de depuración dinámica ), mientras que common.obj (parte del proyecto libprotobuf ) tiene MTd_StaticDebug (enlazando con la versión de depuración estática ), por lo que se vinculan con 2 tiempos de ejecución en el mismo ejecutable, lo que no es posible.

Para solucionarlo, debe asegurarse de que tanto libprotobuf como su proyecto principal tengan el mismo valor para Runtime Library .
Por supuesto, es más fácil cambiar la configuración de su proyecto principal para que coincida con la de libprotobuf , pero se recomienda utilizar la versión de tiempo de ejecución dynamic (las cosas pueden complicarse en proyectos más grandes que tengan .dll s) incluso si esto requiere recomstackr libprotobuf (bien Si cambiar esa opción genera un error que hace que libprotobuf sea muy difícil de comstackr, y su proyecto se mantendrá así de simple, puede usar la versión estática de tiempo de ejecución.

Nota final : no confundir el tipo de biblioteca de tiempo de ejecución (estático / dynamic) con la forma en que se está generando libprotobuf (estático en este punto, pero estoy seguro de que también se puede construir como dynamic).