tutorials the programming plus orwelldevcpp guide dev code blog basics c++ c windows winapi

c++ - the - ¿Por qué funciona MAKEINTRESOURCE()?



the basics of c++ (3)

Esto funciona porque Windows no permite la asignación de páginas para los primeros 64 KB del espacio de direcciones. Para capturar referencias de puntero nulas. Pero también pienso capturar errores de puntero en programas que se convirtieron de la versión de 16 bits de Windows.

Un efecto secundario es que esto permite distinguir de manera confiable las ID de recursos empaquetadas en un valor de puntero, ya que siempre apuntarán a una memoria no asignable.

La macro se define como:

#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i)))) #define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))

¿Por qué se puede usar esto para indicar un ID de recurso (un int sin signo de 16 bits) o su nombre (un puntero a una matriz de caracteres)? ¿No limita esto efectivamente el espacio de direcciones (en un sistema de 32 bits) a 16 bits? De lo contrario, ¿cómo sabe el sistema si estoy usando una identificación o un nombre?


La macro MAKEINTRESOURCE simplemente hace el lanzamiento entre el parámetro numérico y el puntero de cadena. El puntero de cadena resultante no es válido y no se puede anular como nombre de recurso. Sin embargo, la API de manejo de recursos detecta dichos punteros por su valor absoluto y los trata como ID de recurso y no como nombre de recurso. Como la API de estilo C no admite la sobrecarga, no pueden definir dos funciones como:

HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName); HICON LoadIcon(HINSTANCE hInstance,UINT resourceId);

Entonces, los desarrolladores de API decidieron usar la misma función en ambos casos, proporcionando la macro MAKEINTRESOURCE para los usuarios de API. Creo que dos funciones diferentes podrían verse mejor:

HICON LoadIconByName(HINSTANCE hInstance,LPCTSTR lpIconName); HICON LoadIconById(HINSTANCE hInstance,UINT resourceId);

Pero esta no es la forma en que se implementa la API de Windows. El ID de recurso válido siempre es menor que el mínimo valor de puntero posible. El parámetro de nombre de recurso se pasa a la API sin esta macro, y su valor no está restringido.


Sí, limita el espacio de direcciones, pero no tanto como crees. Han efectivamente creado 64KB de su espacio de direcciones de 4GB. La mayoría, si no todos, de esos 64 KB ya están reservados para otras cosas en Windows, por lo que la pérdida efectiva no es nada.

En general, es un ahorro de espacio, ya que no necesitan un bit de información adicional para distinguir entre un puntero y un ID entero. Esto fue inventado en los viejos tiempos, cuando el espacio era escaso.