¿Qué significa la directiva de preprocesamiento #pragma db code?
2. Explicación detallada de las instrucciones pragmáticas de uso común.
1. #Pragma una vez. Asegúrese de que el archivo se incluya solo una vez, que esté basado en el archivo del disco y que #ifndef esté basado en la macro.
2.#Advertencia pragmática Le permite modificar selectivamente el comportamiento de los mensajes de advertencia del compilador. Tiene el siguiente uso:
#pragma Advertencia (disabled: 4507 34; ever: 4385; error: 164) es equivalente a:
#pragma Advertencia (disable: 450734) // no muestra los mensajes de advertencia 4507 y 34.
# pragma advertencia(once:4385)//La información de advertencia 4385 solo se informa una vez.
# pragma advertencia(error:164)//Trate el mensaje de advertencia 164 como un error.
# pragma advertencia (valor predeterminado: 176) //Restablece el comportamiento de advertencia 176 del compilador al estado predeterminado.
Al mismo tiempo, la advertencia pragma también admite el siguiente formato, donde n representa el nivel de advertencia (1-4):
#pragma advertencia(push) //Guardar el mensajes de advertencia existentes de todos los estados de advertencia.
#pragma advertencia(push, n) //Guarde el estado de advertencia existente de todos los mensajes de advertencia y establezca el nivel de alerta global en n.
#pragma advertencia(pop) //Todos los cambios entre HC, Muju y pop serán cancelados.
Por ejemplo:
#Pragma advertencia (push)
#pragma advertencia (deshabilitado: 4705)
#pragma advertencia (deshabilitado :4706)
#pragma advertencia (disabled:4707)
#Pragma advertencia (pop)
Después de este código, restaure todos los mensajes de advertencia (incluidos 4705, 4706 y 4707).
3.#pragma hdrstop. Significa que el archivo de encabezado precompilado termina aquí y los archivos de encabezado posteriores no se precompilarán. BCB puede precompilar archivos de encabezado para acelerar la vinculación, pero si todos los archivos de encabezado están precompilados, puede ocupar demasiado espacio en el disco, así que use esta opción para excluir algunos archivos de encabezado.
4.#Pragma mensaje Muestra la información de texto especificada en el dispositivo de salida estándar sin finalizar el programa. El uso es el siguiente:
#pragma message("texto del mensaje"). Cuando el compilador encuentra esta instrucción, imprime un "texto de mensaje" en la ventana de salida de la compilación.
5.#pragma data_seg. Generalmente utilizado en DLL, puede configurar el segmento de datos donde se ubican las variables de inicialización del programa en el archivo obj. Si no se especifica ningún parámetro, las variables de inicialización se colocarán en la sección de datos predeterminada. Los datos se pueden utilizar de la siguiente manera:
#pragma data_seg("Shared") //Defina el segmento de datos "Compartido", que tiene dos variables A y b.
int a = 0; //Almacenar en el segmento de datos "compartido"
int b; //Almacenar en el segmento de datos ".bss" porque aún no se ha inicializado .
#pragma data_seg() //Indica el final del "compartir" del segmento de datos. Esta línea de código es opcional.
Es muy importante realizar una inicialización especial de las variables; de lo contrario, el compilador colocará la variable en la sección de datos ordinaria no inicializada en lugar de compartirla. Como se mencionó anteriormente, la variable B en realidad se coloca en el segmento de datos no inicializados. bss.
#pragma data_seg("Shared ")
int j = 0; //Almacenado en el segmento de datos "compartido"
# pragma data _ seg ( push, stack1, "Shared2") // Defina el segmento de datos compartido 2, asigne el registro al alias stack1 y luego colóquelo en la pila del compilador interno.
int l = 0; // Almacenado en el segmento de datos "Shared2"
# pragmadata _ seg (pop, stack1) // Extrae registros de la pila del compilador interno hasta que aparece la pila 1. Sin stack1, no se hará nada.
int m = 0; //Almacenado en el segmento de datos "compartido". Si no existe tal segmento pop, la variable se almacenará en el segmento de datos "Shared2".
6.#pragma code_seg. Puede establecer el segmento de código donde se encuentra la función en el programa en el archivo obj. Si no se especifica ningún parámetro, la función se colocará en la sección de código predeterminada. Texto, que se puede utilizar de la siguiente manera:
Void func1() { // Almacenado en el segmento de código. El valor predeterminado es texto.
}
#pragma code_seg(".my_data1 ")
Void func2() { // Almacenado en el segmento de código. mis_datos1.
}
#pragma code_seg(push, r1, ".mydata2")
Void func3() {//Almacenado en segmento de código. Mis datos 2.
}
#pragma code_seg(pop, r1)
Void func4() { // Almacenado en el segmento de código. mis_datos1.
}
7.#Paquete Pragma Se utiliza para cambiar la alineación de bytes del compilador. El uso general es:
#pragma pack(n) //Establece la alineación de bytes del compilador en n, donde el valor de n es generalmente 1, 2, 4, 8, 16, el valor predeterminado es 8 .
#pragma pack(show) // Muestra la alineación de bytes actual como un mensaje de advertencia.
#pragma pack(push) //Coloca la alineación de bytes actual en la pila del compilador interno.
#pragma pack(push, 4) //Coloque la alineación de bytes 4 en la pila del compilador interno y establezca la alineación de memoria actual en 4.
#pragma pack(pop) //Coloca el registro en la parte superior de la pila del compilador interno como la alineación de memoria actual.
#pragma pack(pop, 4) //Coloca el registro en la parte superior de la pila del compilador interno y usa 4 como alineación de memoria actual.
# pragmapack (pop, r1)//r1 es un identificador personalizado que muestra los registros en el compilador interno hasta que aparece r1, y el valor de r1 se usa como la alineación de memoria actual si r1; no existe, entonces no se realiza ninguna acción.
8.#Comentarios pragmáticos. Coloque el registro del comentario en el archivo de destino o en el archivo ejecutable.
El formato es: # pragma comentario (tipo-comentario [, "cadena de comentarios"]). Entre ellos, el tipo de comentario es un identificador predefinido, que especifica el tipo de comentario, que debe ser compilador, exestr, lib, vinculador y usuario.
Compilador: Coloque la versión o el nombre del compilador en el archivo objeto. El vinculador ignora esta opción.
Exestr: Se cancelará en futuras versiones.
Lib: coloca un registro de búsqueda de biblioteca en el archivo objeto, que debe ser el mismo que el tipo de biblioteca especificado por la cadena de comentarios (especifica el nombre y la ruta de la biblioteca que el vinculador buscará).
En el archivo objeto, el nombre de la biblioteca sigue al registro de búsqueda predeterminado; el vinculador busca la biblioteca como si hubiera ingresado el comando en la línea de comando. Puede configurar varios registros de búsqueda de biblioteca en el archivo fuente y aparecerán en el archivo obj en el mismo orden en que aparecen en el archivo fuente.
Si necesita distinguir el orden de las bibliotecas predeterminadas y las bibliotecas adicionales, utilice el modificador de compilación /Zl para evitar que las bibliotecas predeterminadas se coloquen en el módulo de destino.
Enlazador: especifique una opción de enlace para no tener que ingresarla en la línea de comando ni configurarla en el entorno de desarrollo. Solo se pueden pasar las siguientes opciones del vinculador al vinculador:
/biblioteca predeterminada
/export
/includes
/manifest dependence
/Merge
/Parts
(1)/DEFAULTLIB:Library
/La opción DEFAULTLIB agrega la biblioteca a la búsqueda de enlaces cuando resolver referencias en la lista de bibliotecas. Las bibliotecas especificadas con /DEFAULTLIB se buscan después de las bibliotecas especificadas en la línea de comando y antes de las bibliotecas predeterminadas especificadas en el archivo obj.
Anule /DEFAULTLIB:library ignorando todas las opciones de la biblioteca predeterminada (/NODEFAULTLIB). La opción ignorar biblioteca (/NODEFAULTLIB:biblioteca) anulará /DEFAULTLIB:biblioteca si se especifica el mismo nombre de biblioteca en ambas.
(2)/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
Con esta opción, puede exportar funciones de un programa para que otros programas puedan Llámalo o puedes exportar los datos. Las exportaciones generalmente se definen en dlls.
Entryname es el nombre de la función o elemento de datos que utilizará el programa que realiza la llamada. Ordinal es el índice de la tabla de exportación, con un valor que oscila entre 1 y 65535; si no se especifica ningún ordinal, LINK especificará uno. La palabra clave NONAME solo exporta la función como un número de serie, sin nombre de entrada. La palabra clave DATA especifica que los elementos exportados son elementos de datos. Los elementos de datos en el programa cliente deben declararse con __declspec(dllimport) externo.
Según el orden de uso recomendado, hay tres formas de exportar definiciones:
__declspec(dllexport) en el código fuente
En la declaración de exportación. Archivos de definición
Especificaciones en los comandos EXPORT LINK
Los tres métodos se pueden utilizar en el mismo programa. LINK también crea una biblioteca de importación al crear un programa que contiene exportaciones, a menos que . Los archivos exp se utilizan durante el proceso de compilación.
LINK utiliza una forma modificada del identificador. El compilador decora el identificador al crear el archivo obj. Si el nombre de entrada se asigna al vinculador sin modificar (como en el código fuente), LINK intentará hacer coincidir ese nombre. LINK emitirá un mensaje de error si no se encuentra un nombre coincidente único. Cuando necesite asignar un identificador al vinculador, utilice la herramienta Dumpbin para obtener el formato del nombre decorado del identificador.
(3)/Include:symbol
La opción/INCLUDE le dice al vinculador que agregue el símbolo especificado a la tabla de símbolos. Para especificar varios símbolos, escriba una coma (,), punto y coma (;) o espacio. En la línea de comando, /INCLUDE:symbol debe especificarse una vez para cada símbolo.
El vinculador resuelve símbolos agregando un objeto que contiene la definición del símbolo al programa. Esta característica es útil para agregar objetos de biblioteca que no están vinculados al programa.
Los símbolos especificados con esta opción anularán la eliminación de símbolos mediante /OPT:REF.
(4)/manifest dependency:manifest _ dependency
/MANIFESTDEPENDENCY le permite especificar los atributos de un segmento ubicado en el archivo de manifiesto.
La información de /MANIFESTDEPENDENCY se puede pasar a LINK de dos maneras:
Ejecute /MANIFESTDEPENDENCY directamente desde la línea de comando.
Comentar vía #pragma
(5)/Merge: from=to
/Opción MERGE para combinar el primer párrafo (desde) y el segundo párrafo ( to ) y asigne al segmento fusionado el nombre de to.
Si el segundo segmento no existe, LINK cambiará el nombre del segmento (desde) al nombre de hasta.
La opción /MERGE es útil para crear vxds y reescribir nombres de secciones generados por el compilador.
(6)/SECCIÓN:nombre,[[! ]{DEKPRSW}][, ALIGN=#]
/La opción SECTION se utiliza para cambiar los atributos de la sección y anular el conjunto de atributos de la sección al compilar el archivo obj especificado.
Las secciones de un ejecutable portátil (PE) son casi idénticas a las secciones o recursos de un nuevo ejecutable (NE).
Una sección contiene código o datos. A diferencia de un segmento, un segmento es un bloque de memoria contiguo sin límite de tamaño. Algunos segmentos de código o segmentos de datos los define y utiliza directamente su programa, mientras que algunos segmentos de datos los crea el vinculador y el administrador de la biblioteca (lib.exe) y contienen información importante para el sistema operativo.
Los nombres en la opción /SECCIÓN distinguen entre mayúsculas y minúsculas.
No utilice los siguientes nombres ya que entrarán en conflicto con los nombres estándar. Por ejemplo,. sdata es utilizado por la plataforma RISC.
. Arcos
. Especificaciones estándar británicas
. Datos
. datos
. Torre Ida
. datos
. datos
. reubicar
. rsrc
. sbss
. datos
. srdata
. texto
. Datos extendidos
Especifica uno o más atributos para el segmento. Las propiedades no distinguen entre mayúsculas y minúsculas. Para un segmento, debe especificar todos los atributos que desea que tenga; si no se especifica un atributo, se supone que está ausente. Si no se especifican r, w o e, el estado de lectura, escritura o ejecutable existente no se cambiará.
Para darle un significado negativo a un atributo, basta con añadir un signo de exclamación (!).
e: Ejecutable
r: Legible
Mujer: Escribible
s: * * * Carga exclusivamente todo el proceso de imagen de segmento.
d: Desechable
k: No almacenable en caché
p: No paginable
Tenga en cuenta que k y p son números negativos.
Si una sección de un archivo PE no tiene configurado el atributo e, r o w, no es válida.
ALIGN=# opción le permite especificar valores de alineación para segmentos de línea específicos.
Usuario: coloque un comentario general en el archivo objeto y el vinculador ignorará el comentario.
9. Sección #pragma. Crear segmentos de mercado.
El formato es: # pragma sección ("nombre-sección" [atributo]).
Nombre de sección es una opción obligatoria para especificar el nombre de la sección. El nombre no puede entrar en conflicto con el nombre del segmento estándar. Utilice /SECTION para ver una lista de nombres de secciones estándar.
El atributo es opcional y se utiliza para especificar los atributos del segmento. Los atributos disponibles son los siguientes, varios atributos están separados por comas (,):
Leer: legible
Escribir: escribir
Ejecutar: archivo ejecutable
Escribir: escribir
Ejecutar: archivo ejecutable
p>Compartido: Es compartido * * * por todos los procesos que cargan esta imagen de segmento.
Nopage: no se puede paginar, se utiliza principalmente para controladores de dispositivos Win32.
Nocache: No almacenable en caché, se utiliza principalmente para controladores de dispositivos Win32.
Descartar: Desechable, utilizado principalmente para controladores de dispositivos Win32.
Eliminar: No residente en memoria, solo se usa para controladores de dispositivos virtuales (VxD).
Si no se especifica ninguna propiedad, las propiedades predeterminadas son de lectura y escritura.
Después de crear un segmento, también debes usar __declspec(allocate) para colocar código o datos en el segmento.
Por ejemplo:
//pragma_section.cpp
#pragma sección (" mysec ", leer, escribir)
int j = 0;
__declspec(allocate("mysec "))
int I = 0;
int main(){}
En este ejemplo, se crea el segmento "mysec" y se configuran los atributos de lectura, lectura y escritura. Pero j no se coloca en esta sección, sino en la sección de datos predeterminada, porque no está declarado con __declspec(allocate); y yo estoy en esta sección porque está declarado con __declspec(allocate);
10. #pragma push_macro y #pragma pop_macro. El primero coloca la macro especificada en la pila, lo que equivale a un almacenamiento temporal para su uso posterior; el segundo coloca la macro en la parte superior de la pila y la macro extraída sobrescribe la macro con el mismo nombre actual. Por ejemplo:
#includes
#define X 1
#define Y 2
int main() {
printf("%d ",X);
printf("\n%d ",Y);
#Define Y 3 // C4005
#pragma push_macro("Y ")
#pragma push_macro("X ")
printf("\n%d ",X);
#Definición X 2 // C4005
printf("\n%d ", ("\n%d ",X);
#pragma pop_macro("Y " )
printf("\n%d ",Y);
}
Resultado de salida:
1
2
1
2
1
三