Pregunta

¿Es posible construir recursos en una biblioteca estática y reutilizarlos simplemente enlazar con la biblioteca?

Estoy pensando sobre todo sobre el caso en que se llama a una función en la biblioteca que a su vez tiene acceso a los recursos.

¿Fue útil?

Solución

Se puede hacer, pero es muy doloroso:. No puede hacerlo simplemente enlazar con la biblioteca estática

Considere esto: los recursos están incrustados en un archivo EXE o DLL. Cuando algo de código en las llamadas a las bibliotecas estáticas (por ejemplo) LoadIcon, que va a obtener los recursos del EXE o DLL que está vinculado con.

Por lo tanto, si la biblioteca estática requiere recursos que estén disponibles, usted tiene un par de opciones:

  1. Usted puede tener la biblioteca a construir sobre la marcha, y luego usar (por ejemplo) CreateDialogIndirect. Ver rel="noreferrer"> de Raymond Chen .
  2. Puede tener ellos incrustados en la biblioteca arrays como simples (es decir) char my_dialog_resource[] = { .... }; y, a continuación, utilizar (por ejemplo) CreateDialogIndirect. Usted va a necesitar para encontrar (o escribir) una utilidad que convierte los ficheros de .RES a .CPP archivos.
  3. Usted puede enviar el archivo LIB con una presentación (archivo .RC) script del recurso y su correspondiente archivo de cabecera. A continuación, les #include tan relevante. Tendrá que reservar una serie de identificadores de recursos para el LIB de usar, de manera que no choquen con los de la EXE o DLL principal. Esto es lo que hace MFC cuando se utiliza como una biblioteca estática. O puede utilizar los ID de recurso de cadena (esto no funciona para los recursos STRINGTABLE).
  4. Su biblioteca estática puede enviar con una DLL de recursos independiente.

Otros consejos

Lo único que hay que hacer para utilizar los recursos (imágenes, diálogos, etc ...) en una biblioteca estática en Visual C ++ (2008), es Incluir archivo .res asociados de la biblioteca estática en su proyecto. Esto se puede hacer en "Configuración del proyecto / enlazador / input / dependencias adicionales".

Con esta solución, los recursos de la biblioteca estática se empaquetan en el archivo .exe, por lo que no necesita una DLL adicional. Lamentablemente, Visual Studio no incluye el archivo .res automáticamente como lo hace para el archivo .lib (cuando se utilizan las "dependencias del proyecto" -feature), pero creo que este pequeño paso adicional es aceptable.

He buscado durante mucho tiempo para esta solución, y ahora me sorprende es así de simple. El único problema es que está totalmente indocumentado.

acabo de ir a través de este con el MS Visual Studio compilador. Nos convertir algunos proyectos heredados de archivos DLL en bibliotecas estáticas. Varios de estos archivos DLL recursos de diálogo o de cadena incrustados en ellos tenían. Yo era capaz de compilar los scripts .RC para estos archivos DLL en nuestra aplicación principal, incluyéndolos en el archivo de secuencia de comandos RC de la aplicación principal a través del mecanismo de "TEXTINCLUDE". Me pareció más fácil de hacer esto editando el archivo RC directamente, pero Visual Studio proporciona un mecanismo un poco más "wizardy" también. La aplicación es muy probablemente diferente en otros compiladores.


Para manipular el script principal RC directamente:

0.1. En la sección "2 TEXTINCLUDE", incluir el archivo de cabecera que define los identificadores de recursos para su biblioteca. La sintaxis es

2 TEXTINCLUDE 
BEGIN
    "#include ""my_first_lib_header.h""\r\n"
    "#include ""my_second_lib_header.h""\0" 
END

0.2. En la sección "3 TEXTINCLUDE", incluir la secuencia de comandos RC de la biblioteca.

3 TEXTINCLUDE
BEGIN
    "#include ""my_first_library.rc""\r\n"
    "#include ""my_second_library.rc""\0"
END

Los pasos 3 y 4 deben suceder de forma automática, pero me pareció que era más fiable que acaba de entrar en ellos a mí mismo, en lugar de depender de la escritura compilador de recursos de Microsoft para cuidar de las cosas.

0.3. Añadir el archivo de cabecera con sus bibliotecas de recurso define a la lista de símbolos sólo lectura. Esta lista es por lo general cerca de la parte superior del archivo.

#define APSTUDIO_READONLY_SYMBOLS
#include "my_first_lib_header.h"
#include "my_second_lib_header.h"
#undef APSTUDIO_READONLY_SYMBOLS

0.4. Que incluye un script RC de su biblioteca en la sección APSTUDIO_INVOKED. Esto es por lo general en la parte inferior del archivo.

#ifndef APSTUDIO_INVOKED
#include "my_first_library.rc"
#include "my_second_library.rc"
#endif 

También puede hacer todo esto de forma automática a través del IDE de Visual Studio, pero me pareció que no siempre se aplica cuando se esperaba que.

  1. Abre la ventana "Vista de recursos" en Visual Studio.
  2. Haga clic derecho en el archivo de recursos de la aplicación principal y elegir la opción "inclusión de recursos ..." en el menú contextual.
  3. En la casilla de "sólo lectura directivas de símbolos", agregue la incluyen declaraciones de los archivos .h que definen los identificadores de recursos para sus bibliotecas.
  4. "Directivas en tiempo de compilación,"
  5. En la casilla añadir el guión incluyen declaraciones para .rc de su biblioteca.
  6. Haga clic bien. También es posible que desee activar manualmente la compilación guión RC, para asegurarse de que suceda.

Si la escritura de recursos de su biblioteca de referencia a todos los archivos en el disco (archivos de texto, archivos de iconos, etc.), que necesita para asegurarse de que el proyecto principal de la aplicación sabe dónde encontrarlos. Puede copiar estos archivos en algún lugar su aplicación puede encontrarlos o puede agregar un adicional de ruta de inclusión en la configuración del compilador.

Para agregar un adicional de ruta de inclusión:

  1. Abre el diálogo de propiedades para su aplicación principal.
  2. Seleccione "Propiedades de configuración / Recursos / general" en el panel de navegación de la izquierda.
  3. En la lista Propiedades, escriba cualquier ruta pertinentes al lado de "inclusión adicionales directorios."

Yo no lo creo. biblioteca estática no tiene su propio HINSTANCE. Es código se ejecuta en el contexto de la DLL o EXE que lo une. Es por eso que todos los recursos que van a tratar de cargar desde el código de la biblioteca estática será de aquel que encierra DLL / EXE.

Lo hice ese tipo de reutilizar los recursos con una DLL sin embargo, en lo que tiene su propio espacio de direcciones, y se puede llamar LoadResource con HINSTANCE de DLL.

De acuerdo con Visual Studio 2010, las herramientas de desarrollo de Microsoft al parecer no puede manejar apropiadamente compilados los datos de recursos dentro de las bibliotecas estáticas en absoluto.

Para distribuir un archivo de recursos compilado (un archivo .res), tiene dos opciones:

  1. Distribuir los archivos .res por separado, e instruir al código de cliente para enlazar contra ellos;
  2. Uso cvtres a unir varios archivos .res en un archivo único objeto (.obj), y proporcionar por separado.

Tenga en cuenta que no se puede lib en los ficheros objeto creados con cvtres. Si se proporcionan múltiples archivos objeto, lib se queja, como si se les dio como varios archivos .res; Si se proporciona un único archivo de objeto, lib no se queja, pero el enlazador simplemente ignora los datos de recurso incrustado en el archivo lib.

Podría darse el caso de que hay una manera de forzar al enlazador para leer y vincular el libbed de datos de recursos (con alguna opción de línea de comandos, manipulación sección y así sucesivamente), ya que los datos de recursos es de hecho disponible en el biblioteca (como dumpbin revela). Hasta ahora, no he encontrado una solución, y, a menos que uno esté dispuesto a cortar las herramientas de desarrollo, nada mejor que esta sencilla solución es probable que no vale la pena el esfuerzo.

La única manera de enviar datos de recursos en una biblioteca estática (en este caso, por una biblioteca estática) es distribuir los recursos por separado y de forma explícita vincularlos en el código de cliente. Usando cvtres puede reducir el número de archivos de recursos distribuidos a uno, si usted tiene muchos de ellos.

La forma recomendada es proporcionar una DLL con los recursos junto con su biblioteca.

scroll top