Препроцессорные директивы (макросы)
Инструкции препроцессора называются директивами. Они начинаются с символа # и выполнение их происходит на этапе компиляции. Мы уже сталкивались ранее в статьях с директивами препроцессора: #include и #inclib, но давайте рассмотрим их. И не только их.
#INCLUDE
Данная директива позволяет подключать файл к своему проекту. В итоге на то место, где будет записана эта директива при компиляции будет вставлено содержимое файла, указанного после нее в кавычках.
Пример:
#INCLUDE "windows.bi"
#INCLIB
Данная директива позволяет подключать файл статической библиотеки к своему проекту. В итоге на то место, где будет записана эта директива при компиляции будет вставлено содержимое файла, указанного после нее в кавычках. При записи имени файла в кавычках, расширение файла указывать не нужно. Файл будет браться из текущего каталога, либо из каталога компилятора в папке INC. Если имена библиотек в текущем каталоге и в папке INC совпадают, то выбирается содержимое файла в текущем каталоге.
Пример:
#INCLIB "opengl32"
#LIBPATH
Данная директива поможет установить дополнительный каталог для подключения библиотек. Если с директивой используются относительные пути, то путь берется по отношению к рабочей папке проекта.
Пример:
#libpath"C:\" #INCLIB "AAAA"
Данная директива записанная в исходном тексте при компиляции позволяет выводить любую надпись. Ее можно использовать к примеру на больших проектах для визуального определения компилируемого файла.
Пример:
#PRINT file_1.bas full compiling
Кавычки для строки file_1.bas full compiling не требуются. Теперь
если поместить всю эту строку в конец исходного кода, то после компиляции в окне
команд будет высвечиваться эта надпись, оповещающая, что файл
откомпилирован.
#ERROR
Эта директива может быть полезна для того, чтобы останавливать выполнение компиляции , например если что-то пошло не так. Если вставить ее в ваш исходный код, то она остановит компиляцию и выведет нужную строку.
Пример:
#ERROR file 2.bi Not found
Конечно эта директива будет глупо смотреться без определенных условий компиляции. Их мы рассмотрим, только ниже.
#DEFINE
Эта директива позволяет определить макрос. Макросы часто используются программистами для облегчения понимания кода, да и самого программирования тоже. Макрос позволяет заменить сложную строку с командами или просто какую то строку, простым и понятным именем. Так к примеру макрос RGB (r,g,b) представляет из себя реальную запись:
(Cuint(r) Shl 16) Or (Cuint(g) Shl 8) Or Cuint(b) Or &hFF000000
Сами понимаете как удобнее записывать. С помощью #define можно определять
все что хочется. На самом деле немалая часть встроенных команд языка Freebasic -
это определенные макросы.
Определяются макросы записью, начинающейся с
#define. Далее следует имя макроса, которое в дальнейшем будет
использоваться в нужных местах кода. И наконец значение, которое при компиляции
будет подставляться в код вместо имени.
Пример простого макроса:
#DEFINE PI 3.1415926535897932
Теперь где бы мы не вставляли слово PI , при компиляции будет заменено на
настоящее значение 3.14.....
При объявлении макроса можно производить любые действия:
#DEFINE SummaString(x,y) Str(x)+Str(y) ? SummaString(167,382) ? SummaString("Ivan"," Sidorov") Sleep
#MACRO
#define конечно удобен для создания макроса, но часто нужен макрос, состоящий из большого числа строк. В этом случае может выручить блок #macro - #endmacro.
Пример_1 (без параметров):
#INCLUDE "windows.bi" #MACRO Text() "Однажды Мастер Никеда сказал своим ученикам:" & !"\r\n" &_ "— В мире нет Абсолютной Истины." & !"\r\n" &_ "Один из учеников спросил:" & !"\r\n" &_ "— А эта истина абсолютна?" & !"\r\n" &_ "— Нет, конечно, — улыбнулся Мастер." & !"\r\n" #ENDMACRO MessageBox(0,Text(),"Притча",0)
В этом примере записан макрос Text , которой представляет из себя форматированный текст. Не пугайтесь записи !"\r\n" это форматирующие символы для перевода строк. Вместо этого можно было записать так: chr(13) & chr(10)
Пример_2 (с параметрами):
#MACRO SWAP_(a,b) Scope Var c=a a=b b=c End Scope #ENDMACRO Dim As Integer x=10,y=20 SWAP_(x,y) ? x,y Sleep
В примере выше макрос обменивает значения у переменных.
#UNDEF
Данная директива позволяет отменять объявленный макрос.
Пример:
#INCLUDE "windows.bi" #Undef Print #DEFINE Print(a) MessageBox(0,a,"",0) Print ("FreeBasic")
В данном примере мы отменили встроенный в Freebasic макрос Print и объявили для него другую функциональную возможность.
#iF , #ELSEIF , #ELSE, #ENDIF , #iFDEF , #IFNDEF И DEFINED
Директивы условной компиляции предназначены для включения или отключения компиляции отдельных частей в зависимости например от платформы, или от версии программы. Объяснять суть #If , #elseif , #else, #endif наверно не стоит. Если вы читали статью о логических операторах , то смысл их работы должен быть понятен. Единственно что стоит упомянуть: при использовании этих директив не нужно (нельзя) указывать THEN.
Пример:
#DEFINE version lite #IF version=lite #PRINT Start compile lite version #ELSE #PRINT Start compile full version #ENDIF
Директивы:
#IFDEF - если объявлена
#IFNDEF - если не объявлена
DEFINED - если
объявлена
Могут так же использоваться для проверки объявления переменных, констант и пр. Это особенно полезно при использовании включаемых файлов, в которых они могут быть уже объявлены. Это поможет избежать ошибок при компиляции.
Пример_1:
Dim a As Integer #IFNDEF a Dim a As Integer #ELSE Print "a declared" #ENDIF Sleep
Пример_2:
Const a As Integer=45 #IF DEFINED(a) Print "a declared" #ELSE Print "a not declared" #ENDIF Sleep
Предопределенные макросы
Эти макросы выдают информацию о платформе, версии компилятора , процессе
компиляции и др.
Используемые для проверки платформы:
__FB_WIN32__ -
Windows
__FB_LINUX__ -
Linux
__FB_DOS__ - DOS
Есть еще макросы определения других платформ, однако эти платформы не используются в FreeBasic, если интересно читаем в справке.
Пример:
#IFDEF __FB_WIN32__ ' объявления и инструкции для платформы Windows #ELSEIF __FB_LINUX__ ' объявления и инструкции для платформы Linux #ENDIF
Связанные с получением информации о версии компилятора:
- __FB_VERSION__ - возвращает версию компилятора
- __FB_VER_MAJOR__ - возвращает номер версии
- __FB_VER_MINOR__ - возвращает расширение номера версии
- __FB_VER_PATCH__ - возвращает версию обновления
- __FB_MIN_VERSION__( major, minor, patch) - устанавливает минимальную версию для компиляции
- __FB_BUILD_DATE__ - возвращает дату компиляции в формате день-месяц-год
- __FB_SIGNATURE__ - возвращает версию компилятора по сигнатуре
Пример:
Print __FB_VERSION__ 'версия компилятора Print __FB_VER_MAJOR__ ' номер версии Print __FB_VER_MINOR__ ' расширение номера версии Print __FB_VER_PATCH__ ' версия обновления Print __FB_BUILD_DATE__ ' дата компиляции Print __FB_SIGNATURE__ ' версия компилятора по сигнатуре #IF __FB_MIN_VERSION__(0, 22, 0)'ставим минимальную версию 0.22 #PRINT Start compiling #ENDIF Sleep
Связанные с получением информации о текущем компилируемом модуле:
- __FB_MAIN__ - определение компилирования главного модуля
- __FB_DEBUG__ - определяет режим компиляции с отладочной информацией. Если была определена опция возвращает -1
- __FB_ERR__ - возвращает режим включения проверки ошибок: (0,1,3,7)
- 0 - не используется
- 1 - выборочный режим отлова ошибок
- 3 - стиль Qbasic
- 7 - проверка ошибок по максимуму
- __FB_LANG__ - возвращает языковый режим совместимости
- ''fb'' - Freebasic
- ''qb'' - Совместимая с Qbasic
- ''fblite'' - Версия более или менее совместимая с Qbasic
- ''deprecated'' - Прошлые версии FreeBasic
- __FB_MT__ - определяет использование RunTime Library для многопоточных приложений. Если была определена опция возвращает -1
- __FB_OUT_DLL__ - определяет что компилируется DLL . Если была определена опция возвращает -1
- __FB_OUT_EXE__ - определяет что компилируется EXE . Если была определена опция возвращает -1
- __FB_OUT_LIB__ - определяет что компилируется статическая библиотека . Если была определена опция возвращает -1
- __FB_OUT_OBJ__ - определяет что компилируется объектный файл. Если была определена опция возвращает -1
Пример:
#IFDEF __FB_MAIN__ #PRINT Main module #ENDIF #IF __FB_DEBUG__ #PRINT Debug mode #ELSE #PRINT Not Debug mode #ENDIF #IF __FB_ERR__ =0 #PRINT Not Checking #ELSEIF __FB_ERR__ =1 #PRINT Some Checking #ELSEIF __FB_ERR__ =3 #PRINT Qbasic Style Checking #ELSEIF __FB_ERR__ =7 #PRINT SuperChecking #ENDIF #IF __FB_LANG__ ="fb" #PRINT Using Modern FreeBasic #ELSEIF __FB_LANG__ ="qb" #PRINT Using Qbasic #ELSEIF __FB_LANG__ ="fblite" #PRINT Using FreeBasic Some compatibility QBasic #ELSEIF __FB_LANG__ ="deprecated" #PRINT Using old FreeBasic #ENDIF #IF __FB_MT__ =-1 #PRINT Using multi-threaded library #ENDIF #IF __FB_MT__ =-1 #PRINT Using multi-threaded library #ENDIF #IF __FB_OUT_DLL__ =-1 #PRINT Compile DLL Library #ELSEIF __FB_OUT_EXE__ =-1 #PRINT Compile EXE file #ELSEIF __FB_OUT_LIB__ =-1 #PRINT Compile Static Library #ELSEIF __FB_OUT_OBJ__ =-1 #PRINT Compile Object file #ENDIF
После компиляции этого примера с такой командой: fbc -s console , в командной строке должно высветиться:
fbc -s console "FbTemp.bas" Main module Not Debug mode Not Checking Using Modern FreeBasic Compile EXE file Make done
Другие макросы
- __DATE__ - возвращает дату компиляции
- __TIME__ - возвращает время компиляции
- __PATH__ - возвращает путь к исходному файлу
- __FILE__ - возвращает имя текущего файла с кавычками
- __FILE_NQ__ - возвращает имя текущего файла без кавычек. Нельзя использовать для обычной команды Print
- __FUNCTION__ - возвращает название функции с кавычками в которой записана
- __FUNCTION_NQ__ - возвращает название функции без кавычек в которой записана. Может использоваться для получения адреса функции, но нельзя использовать для обычной команды Print
- __LINE__ - возвращает номер строки на которой записана
Пример:
? __DATE__ ? __TIME__ ? __PATH__ ? __FILE__ ? __LINE__ #PRINT __FILE_NQ__ Sub MySub Print "Address of " + __FUNCTION__ + " is "; Print Hex( @__FUNCTION_NQ__ ) End Sub MySub Sleep
Это все по макросам. Всего доброго!
содержание | назад | вперед