2010-05-29 16 views

Respuesta

52

Puesto que usted está trabajando en una aplicación nativa de Windows, lo que quiere do es crear un recurso definido por el usuario para incrustar el contenido del archivo de texto en el recurso compilado.

El formato de un recurso definido por el usuario es documented on MSDN, al igual que the functions for loading it.

incrustar su archivo de texto en un archivo de recursos como esto:

nameID typeID filename 

donde nameID es algunas únicas entero sin signo de 16 bits que identifica el recurso y typeID es algunas únicas entero de 16 bits sin signo mayor que 255 que identifica el tipo de recurso (puede definir esos enteros en el archivo resource.h). filename es la ruta al archivo que desea incrustar sus contenidos binarios en el recurso compilado.

lo que podría tener de esta manera:

En resource.h:

// Other defines... 

#define TEXTFILE  256 
#define IDR_MYTEXTFILE 101 

En el archivo de recursos:

#include "resource.h" 

// Other resource statements... 

IDR_MYTEXTFILE TEXTFILE "mytextfile.txt" 

Luego se carga como esto (código de comprobación de errores omite para mayor claridad):

#include <windows.h> 
#include <cstdio> 
#include "resource.h" 

void LoadFileInResource(int name, int type, DWORD& size, const char*& data) 
{ 
    HMODULE handle = ::GetModuleHandle(NULL); 
    HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name), 
     MAKEINTRESOURCE(type)); 
    HGLOBAL rcData = ::LoadResource(handle, rc); 
    size = ::SizeofResource(handle, rc); 
    data = static_cast<const char*>(::LockResource(rcData)); 
} 

// Usage example 
int main() 
{ 
    DWORD size = 0; 
    const char* data = NULL; 
    LoadFileInResource(IDR_MYTEXTFILE, TEXTFILE, size, data); 
    /* Access bytes in data - here's a simple example involving text output*/ 
    // The text stored in the resource might not be NULL terminated. 
    char* buffer = new char[size+1]; 
    ::memcpy(buffer, data, size); 
    buffer[size] = 0; // NULL terminator 
    ::printf("Contents of text file: %s\n", buffer); // Print as ASCII text 
    delete[] buffer; 
    return 0; 
} 

Tenga en cuenta que en realidad no tiene que liberar el recurso ya que el recurso reside en el binario del ejecutable y el sistema lo eliminará automáticamente cuando el programa salga (la función FreeResource() no hace nada en Windows de 32 bits y 64 bits sistemas).

Como los datos se encuentran en el binario ejecutable, no se puede modificar directamente mediante el puntero recuperado (es por eso que la implementación de la función LoadFileInResource() almacena el puntero en const char*). Necesita hacer uso de las funciones BeginUpdateResource(), UpdateResource() y EndUpdateResource() para hacerlo.

+0

Tengo una pregunta más en general preguntada [aquí] (http://stackoverflow.com/questions/35521857/best-practice-to-protect-resources-against-reverse-engineering). ¿Podría responder a mi segunda pregunta relacionada con su respuesta?Solo cómo tener un archivo dll que tenga una función para contener el código que está en principal en su respuesta. – utvecklare

+0

"el sistema los eliminará automáticamente cuando el programa salga" ¿No todo programa al salir de los recursos gratuitos del sistema? Se produce una fuga de memoria y una pérdida de recursos durante la ejecución de un ejecutable. Entonces, si este programa carga n del mismo recurso, emitirá una fuga de recursos. – Raindrop7

+0

En las propiedades del archivo de recursos hay "Cadenas de terminación nula" –

-2

Puede usar xxd (desde una máquina Linux o probablemente cygwin) para generar los datos para un archivo .h/.cc.

Hay un montón de preguntas de desbordamiento de pila que se expanden sobre esto en detalle:

+6

-1 Los archivos PE (+) ya son capaces de almacenar recursos personalizados, y las herramientas de compilación de Windows tienen todo lo que necesita. La sintaxis del script de recursos está documentada y el sistema operativo proporciona API para acceder a esos datos. Esta respuesta es la respuesta a otra pregunta. – IInspectable

Cuestiones relacionadas