Subversion Repositories Kolibri OS

Rev

Rev 1373 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1127 Lrz 1
Руководство программиста по использованию макросов для универсальной загрузки библиотеки/библиотек
2
от 6 июля 2009г.
3
 
4
Copyright (c) 2009, 
5
All rights reserved.
6
 
7
        Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
Neither the name of the  nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
 
12
        THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka  ''AS IS'' AND ANY
13
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE MPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14
        LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
*****************************************************************************Изменения:
16
 
17
Доработан макрос, убраны ограничения при его использовании. Вывод сообщений об ошибках производиться в отдельном потоке. При пакетной обработке загрузки библиотек, в начале формируется все сообщения от библиотек, которые загружены с ошибками, и затем произведен вывод на экран отдельным потоком со всем списком ошибок.Введение:
18
 
19
        В последнее время наметилась тенденция в переносе основных, базовых блоков (компонентов) в библиотеки. Для разработчика это является очень удобно, т.к. сроки разработки программы значительно сокращаются. Макрос load_lib.mac разрабатывался как универсальный для загрузки любого количества библиотек. Особенностью его является то, что если библиотека не может быть найдена по указанному пути, или существует ошибка при импорте, то тогда, формируется сообщение и выводиться в окне информация об ошибке. Поиск библиотеки происходит по 2-м направлениям. В текущей папке, откуда стартовала программа и в системной папке (по указанному пути + название библиотеки).
20
Структура макросов:
21
 
22
        Файл load_lib.mac состоит из 5 основных макросов.
23
Для загрузки одной библиотеки существуют макросы первой группы, назовем, ее группа А.  Для загрузки от 2-х и более библиотек созданы макросы группы B. Название этих макросов:
24
 
25
A:
26
sys_load_library
27
load_library
28
B:
29
sys_load_libraries
30
load_libraries
31
 
32
        Для макросов группы А необходимо в качестве параметров указать следующие опции:
33
library_name, cur_dir_path, library_path, system_path, err_message_found_lib, head_f_l, myimport, err_message_import, head_f_i . Синтаксически правильно использовать следующию запись для правильного разворачивания макроса:
34
 
35
sys_load_library library_name, cur_dir_path, library_path, system_path, err_message_found_lib, head_f_l, myimport, err_message_import, head_f_i
36
 
37
или
38
 
39
load_library library_name, cur_dir_path, library_path, system_path, err_message_found_lib, head_f_l, myimport, err_message_import, head_f_i
40
 
41
        Разница между этими двумя макросами только в порядке проверки пути к библиотеке.
42
sys_load_library - в первую очередь проверяется значение указанное в system_path, т.е. на этом месте где находится system_path должен быть помещен адрес записи.
43
 
44
Всегда соблюдать последовательность в имени.
45
system_path      db '/sys/lib/'
46
library_name     db 'box_lib.obj',0     ; такая запись сделана из экономии места
47
 
48
Если есть желание разъединить, то нужно использовать следующую конструкцию
49
system_path      db '/sys/lib/box_lib.obj',0
50
... любая последовательность других команд и определений.
51
library_name     db 'box_lib.obj',0
52
 
53
 
54
А load_library - в первую очередь проверяет текущую папку, т.е. использует этот путь для поиска библиотеки.
55
 
56
library_name - имя библиотеки обычно в данных определяется как
57
library_name     db 'box_lib.obj',0
58
 
59
Иногда, возникает необходимость загрузки библиотеки с папки, которая находиться ниже уровнем директории, с которой была запущена программа. Допустим, следующее:
60
 
61
 
62
Необходимая нам библиотека расположена в папке ff2, для того, что бы макрос загрузил библиотеку из этой папки, нам нужно сделать следующее:
63
 
64
Обращаю внимание, что короткая запись в этом случае невозможна, и нужно определить следующие пути полностью.
65
system_path      db '/sys/lib/tread_lib.obj',0
66
;... любая последовательность других команд и определений.
67
library_name     db 'ff2/tread_lib.obj',0
68
- именно такое определение имени, позволит динамически сформировать путь до нашей бибилотеки.
69
 
70
cur_dir_path - первоначально должен быть определен в заголовке программы, как:
71
 
72
use32                   ; транслятор, использующий 32 разрядных команды
73
    org 0x0             ; базовый адрес кода, всегда 0x0
74
    db 'MENUET01'       ; идентификатор исполняемого файла (8 байт)
75
    dd 0x1              ; версия формата заголовка исполняемого файла
76
    dd start            ; адрес, на который система передаёт управление
77
                        ; после загрузки приложения в память
78
    dd i_end            ; размер приложения
79
    dd mem              ; Объем используемой памяти, для стека отведем 0х100 байт и выровним на грницу 4 байта
80
    dd mem              ; расположим позицию стека в области памяти, сразу за телом программы. Вершина стека в диапазоне памяти, указанном выше
81
    dd 0x0              ; указатель на строку с параметрами.
82
    dd cur_dir_path     ; указатель на адрес, куда помещается строка, содержащая путь до программы в момент запуска.
83
а затем в секции DATA программы
84
 
85
cur_dir_path    rb 4096 ; значение 4096 может быть и меньше, но должно вмещать полностью путь до библиотеки. Т.е. это буфер, в котором формируется путь при запуске программы.
86
 
87
library_path - начало буфера, в котором будет сформирован путь полученный при запуске программы с именем библиотеки.
88
library_path    rb 4096
89
 
90
system_path - путь до библиотеки с именем библиотеки. Предполагаем, что, тут указан полный путь до библиотеки.
91
Всегда соблюдать последовательность в имени.
92
system_path      db '/sys/lib/'
93
library_name     db 'box_lib.obj',0     ; такая запись сделана из экономии места
94
 
95
Если есть желание разъединить, то нужно использовать следующую конструкцию
96
system_path      db '/sys/lib/box_lib.obj',0
97
... любая последовательность других команд и определений.
98
library_name     db 'box_lib.obj',0
99
 
100
err_message_found_lib - строка, которая будет в сформированном окне, если библиотека не будет найдена.
101
 
102
err_message_found_lib   db 'Sorry I cannot load library box_lib.obj',0
103
 
104
head_f_l -  заголовок окна, при возникновении ошибки - библиотека не найдена.
105
head_f_l        db 'System error',0
106
 
107
myimport -  указатель на импорт функций из библиотеки.
108
myimport:
109
 
110
edit_box_draw   dd      aEdit_box_draw
111
edit_box_key    dd      aEdit_box_key
112
edit_box_mouse  dd      aEdit_box_mouse
113
version_ed      dd      aVersion_ed
114
 
115
check_box_draw  dd      aCheck_box_draw
116
check_box_mouse dd      aCheck_box_mouse
117
version_ch      dd      aVersion_ch
118
 
119
option_box_draw  dd      aOption_box_draw
120
option_box_mouse dd      aOption_box_mouse
121
version_op       dd      aVersion_op
122
 
123
                dd      0
124
                dd      0
125
 
126
aEdit_box_draw  db 'edit_box',0
127
aEdit_box_key   db 'edit_box_key',0
128
aEdit_box_mouse db 'edit_box_mouse',0
129
aVersion_ed     db 'version_ed',0
130
 
131
aCheck_box_draw  db 'check_box_draw',0
132
aCheck_box_mouse db 'check_box_mouse',0
133
aVersion_ch      db 'version_ch',0
134
 
135
aOption_box_draw  db 'option_box_draw',0
136
aOption_box_mouse db 'option_box_mouse',0
137
aVersion_op       db 'version_op',0
138
 
139
err_message_import - строка, которая будет в сформированном окне, если при импорте функций произошла ошибка.
140
 
141
err_message_import      db 'Error on load import library box_lib.obj',0
142
 
143
head_f_i - заголовок окна, при возникновении ошибки - ошибка импорта функций.
144
head_f_i        db 'System error',0
145
 
146
        После того, как макрос будет раскрыт и отработает свою часть кода, можно узнать об успешности или не успешности загрузки, импорте библиотеки. В регистре еax формируется 0 при успешной загрузке и импорте, или -1, если на любом из этих этапов возникла ошибка. При возникновении ошибки рекомендуется завершить выполнение программы.
147
        cmp     eax,-1
148
        jz      exit
149
 
150
Группа макросов B
151
 
152
        Основным отличием макросов группы А, от группы B является блочная (пакетная) обработка загрузки большого количестве библиотек. Так же, больше информации можно получить после обработки пакета. Так, при пакетной обработке получаем код возврата, который содержит 2 типа кодов ошибок:
153
Не нашли либу
154
Не смогли импортировать функции.
155
 
156
B:
157
sys_load_libraries
158
load_libraries
159
 
160
        Для макросов группы B необходимо в качестве параметров указать следующие опции:
161
начало блока данных структур и конец load_libraries l_libs_start,end_l_libs, где
162
 
163
l_libs_start:
164
library01  l_libs boxlib_name, path, file_name, system_dir, \
165
er_message_found_lib, ihead_f_l, myimport, er_message_import, ihead_f_i
166
 
167
library02  l_libs plugin_BMP_name, path, file_name, system_dir1,\
168
er_message_found_lib2, ihead_f_l, myimport, er_message_import2, ihead_f_i
169
end_l_libs:
170
 
171
Вот такая запись
172
library01  l_libs boxlib_name, path, file_name, system_dir, \
173
er_message_found_lib, ihead_f_l, myimport, er_message_import, ihead_f_i
174
раскрывается в следующее:
175
 
176
.library_name   dd library_name
177
.cur_dir_path   dd cur_dir_path
178
.library_path   dd library_path
179
.system_path    dd system_path
180
.err_message_found_lib   dd err_message_found_lib
181
.head_f_l       dd head_f_l
182
.my_import      dd my_import
183
.err_message_import      dd err_message_import
184
.head_f_i       dd head_f_i
185
;выше полностью соответствует значениям для параметров группы макросов А.
186
.adr_load_lib   dd 0x0          ; адрес загруженной библиотеки
187
.status_lib     dd 0x0          ;status of load library - статус коды могут принимать значение 0 - успешно, 0х1 - ошибка поиска библиотеки, 0х2 - ошибка импорта функций.
188
 
189
Если нужно узнать программе, как загрузилась библиотека, используем следующую проверку:
190
 
191
;проверка на сколько удачно загрузилась наша библиотека
192
        mov     ebp,library01 - метка структуры
193
        cmp     dword [ebp+ll_struc_size-4],0 ; тут проверяем код статуса возврата
194
        jnz     exit ;если не 0, то уходим.
195
 
196
 
197
;получение адреса загруженной библиотеки
198
        mov     ebp,library01 - метка структуры
199
        cmp     dword [ebp+ll_struc_size-4],0 ; тут проверяем код статуса возврата
200
        jnz     exit ;если не 0, то уходим.
201
        mov     ebp, dword [ebp+ll_struc_size-8] - в ebp адрес начала.
202
 
1488 IgorA 203
Макорос @use_library
1127 Lrz 204
 
1488 IgorA 205
Этот макрос представляет вызываемые процедуры, которые используются для работы групп макросов А и B. Данный макрос располагается в секции дата. Использование данного макроса нужно для загрузки библиотек но его можно заменять на @use_library_mem.
1127 Lrz 206
 
207
 
1488 IgorA 208
Макорос @use_library_mem mem_alloc,mem_free,mem_realloc,dll_load
209
 
210
Этот макрос использует макрос @use_library, но в отличие от него он позволяет для функций с именами 'lib_init' задавать 4 параметра. В даных параметрах могут быть указатели на функции для работы с памятью, которые могут быть нужны для использования внутри библиотеки.
211
 
212
 
1127 Lrz 213
Как я могу использовать макрос загрузки библиотеки/библиотек в своей программе?
214
 
215
Общий шаблон для использования библиотеки такой:
216
 
217
use32                ; транслятор, использующий 32 разрядных команды
218
    org 0x0                ; базовый адрес кода, всегда 0x0
219
    db 'MENUET01'        ; идентификатор исполняемого файла (8 байт)
220
    dd 0x1                ; версия формата заголовка исполняемого файла
221
    dd start                ; адрес, на который система передаёт управление
222
                        ; после загрузки приложения в память
223
    dd i_end                ; размер приложения
224
    dd mem                  ; Объем используемой памяти, для стека отведем 0х100 байт и выровним на грницу 4 байта
225
    dd mem                  ; расположим позицию стека в области памяти, сразу за телом программы. Вершина стека в диапазоне памяти, указанном выше
226
    dd 0x0              ; указатель на строку с параметрами.
227
    dd cur_dir_path
228
include 'macros.inc'
1373 IgorA 229
include 'box_lib.mac'
1127 Lrz 230
include 'load_lib.mac'
231
        @use_library    ;use load lib macros
232
start:
233
;universal load library/librarys
234
sys_load_library  library_name, cur_dir_path, library_path, system_path, \
235
err_message_found_lib, head_f_l, myimport, err_message_import, head_f_i
236
;if return code =-1 then exit, else nornary work
237
        cmp     eax,-1
238
        jz      exit
239
        mcall   40,0x27         ;установить маску для ожидаемых событий
240
red_win:
241
    call draw_window            ;первоначально необходимо нарисовать окно
242
align 4
243
still:                          ;основной обработчик
244
        mcall   10              ;Ожидать события
245
        dec  eax
246
        jz   red_win
247
        dec  eax
248
        jz   key
249
        dec  eax
250
        jz   button
251
 
252
        push    dword edit1
253
        call    [edit_box_mouse]
254
 
255
        push    dword edit2
256
        call    [edit_box_mouse]
257
 
258
        push    dword check1
259
        call    [check_box_mouse]
260
 
261
        push    dword check2
262
        call    [check_box_mouse]
263
 
264
        push    dword Option_boxs
265
        call    [option_box_mouse]
266
 
267
        push    dword Option_boxs2
268
        call    [option_box_mouse]
269
 
270
        jmp still    ;если ничего из перечисленного то снова в цикл
271
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
272
button:
273
        mcall   17      ;получить идентификатор нажатой клавиши
274
        test ah,ah      ;если в ah 0, то перейти на обработчик событий still
275
        jz  still
276
exit:   mcall   -1
277
key:
278
        mcall   2       ;загрузим значение 2 в регистор eax и получим код нажатой клавиши
279
 
280
        push    dword edit1
281
        call    [edit_box_key]
282
 
283
        push    dword edit2
284
        call    [edit_box_key]
285
 
286
        jmp still
287
 
288
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
289
align 4
290
draw_window:            ;рисование окна приложения
291
        mcall   12,1
292
        mcall   0,(50*65536+390),(30*65536+200),0x33AABBCC,0x805080DD,hed
293
 
294
        push    dword edit1
295
        call    [edit_box_draw]
296
 
297
        push    dword edit2
298
        call    [edit_box_draw]
299
 
300
        push    dword check1
301
        call    [check_box_draw]
302
 
303
        push    dword check2
304
        call    [check_box_draw]
305
 
306
        push    dword Option_boxs
307
        call    [option_box_draw]
308
 
309
        push    dword Option_boxs2
310
        call    [option_box_draw]
311
 
312
        mcall   12,2
313
    ret
314
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
315
;DATA данные
316
;Всегда соблюдать последовательность в имени.
317
system_path      db '/sys/lib/'
318
library_name     db 'box_lib.obj',0
319
; Если есть желание разъединить, то нужно использовать следующию конструкцию
320
;system_path      db '/sys/lib/box_lib.obj',0
321
;... любая последовательность других команд и определений.
322
;library_name     db 'box_lib.obj',0
323
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
324
 
325
err_message_found_lib   db 'Sorry I cannot load library box_lib.obj',0
326
head_f_i:
327
head_f_l        db 'System error',0
328
err_message_import      db 'Error on load import library box_lib.obj',0
329
 
330
myimport:
331
 
332
edit_box_draw   dd      aEdit_box_draw
333
edit_box_key    dd      aEdit_box_key
334
edit_box_mouse  dd      aEdit_box_mouse
335
version_ed      dd      aVersion_ed
336
 
337
check_box_draw  dd      aCheck_box_draw
338
check_box_mouse dd      aCheck_box_mouse
339
version_ch      dd      aVersion_ch
340
 
341
option_box_draw  dd      aOption_box_draw
342
option_box_mouse dd      aOption_box_mouse
343
version_op       dd      aVersion_op
344
 
345
                dd      0
346
                dd      0
347
 
348
aEdit_box_draw  db 'edit_box',0
349
aEdit_box_key   db 'edit_box_key',0
350
aEdit_box_mouse db 'edit_box_mouse',0
351
aVersion_ed     db 'version_ed',0
352
 
353
aCheck_box_draw  db 'check_box_draw',0
354
aCheck_box_mouse db 'check_box_mouse',0
355
aVersion_ch      db 'version_ch',0
356
 
357
aOption_box_draw  db 'option_box_draw',0
358
aOption_box_mouse db 'option_box_mouse',0
359
aVersion_op       db 'version_op',0
360
 
361
 
362
 
363
 
364
check1 check_box 10,45,6,12,0x80AABBCC,0,0,check_text,14,ch_flag_en
365
check2 check_box 10,60,6,12,0x80AABBCC,0,0,check_text2,15
366
 
367
edit1 edit_box 350,3,5,0xffffff,0x6f9480,0,0xAABBCC,0,308,hed,ed_focus,hed_end-hed-1,hed_end-hed-1
368
edit2 edit_box 350,3,25,0xffffff,0x6a9480,0,0,0,99,ed_buffer,ed_figure_only
369
 
370
op1 option_box option_group1,10,90,6,12,0xffffff,0,0,op_text.1,op_text.e1-op_text.1
371
op2 option_box option_group1,10,105,6,12,0xFFFFFF,0,0,op_text.2,op_text.e2-op_text.2
372
op3 option_box option_group1,10,120,6,12,0xffffff,0,0,op_text.3,op_text.e3-op_text.3
373
op11 option_box option_group2,120,90,6,12,0xffffff,0,0,op_text.1,op_text.e1-op_text.1
374
op12 option_box option_group2,120,105,6,12,0xffffff,0,0,op_text.2,op_text.e2-op_text.2
375
op13 option_box option_group2,120,120,6,12,0xffffff,0,0,op_text.3,op_text.e3-op_text.3
376
 
377
option_group1   dd op1  ;указатели, они отображаются по умолчанию, когда выводится
378
option_group2   dd op12 ;приложение
379
Option_boxs     dd  op1,op2,op3,0
380
Option_boxs2    dd  op11,op12,op13,0
381
hed db   'BOXs load from lib  date 27.04.2009',0
382
hed_end:
383
rb  256
384
check_text db 'First checkbox'
385
check_text2 db 'Second checkbox'
386
op_text:                ; Сопровождающий текст для чек боксов
387
.1 db 'Option_Box #1'
388
.e1:
389
.2 db 'Option_Box #2'
390
.e2:
391
.3 db 'Option_Box #3'
392
.e3:
393
ed_buffer       rb 100
394
;-----------------------
395
;sc      system_colors
396
p_info  process_information
397
cur_dir_path    rb 4096
398
library_path    rb 4096
399
i_end:
400
rb 1024
401
mem: