Менеджер DLL в MeOS

Discussing libraries simplifying applications development
  • Чтобы не возиться с ассемблерными вставками надо объявить все импортируемые функции через указатели

    Code: Select all

    //это вариант для MSVC
    
    extern void (_stdcall *dll_start)(int);
    extern void (_stdcall *con_init)(dword wnd_width, dword wnd_height,
           dword scr_width, dword scr_height, const char* title)
    extern void (_stdcall *con_write_asciiz)(dword flags, const char* string);
    
    if( !dll_start(DLL_ENTRY))
    {
    
    //что-то не так
    
      exit();
    
    }
    в asm файле

    Code: Select all

    imports:
    _dll_start          dd szStart
    _dll_ver            dd szVersion
    _con_init           dd szcon_init
    _con_write_asciiz   dd szcon_write_asciiz
    _con_printf         dd szcon_printf
    _con_exit           dd szcon_exit
                        dd 0                //завершает массив
    
    szStart             db 'START',0
    szVersion           db 'version',0
    szcon_init          db 'con_init',0
    szcon_write_asciiz  db 'con_write_asciiz',0
    szcon_printf        db 'con_printf',0
    szcon_exit          db 'con_exit',0
    я не знаю если способ создать массив imports на C. Вероятно потребуется очень громоздкое приведение типов из указателя на строку в указатель на функцию если оно вообще возможно.
  • Serge wrote:maxxx

    Для программ в примере testcon2.asm есть функции link и get_proc. Проще и быстрее включить их код в программу чем делать системный вызов. Особенно с фунцией link которая сама делает всё необходимое связывание. get_proc нужна только если требуется адрес конкретной функции.
    для разработчика будет проще вызвать загрузку dll которая уже реализована в ядре, и вызвать функцию загрузки как массива импортируемых функций, так и отдельную функцию.

    в любом случае в ядре уже реализованы как get_proc (одна функция), так и get_proc_ex (массив), так зачем прикладному программисту каждый раз включать в свой код процедуру get_proc/ex если можно их сделать доступными?

    ядро должно предоставлять не только загрузку длл но и получение адреса функции из длл обеих версий посредством системных вызовов. лишний раз городить код в программе неразумно, если есть его аналоги в ядре
  • maxxx

    get_proc из ядра не годится для приложений. У ядра базовый адрес сегментов 0 а у программ std_application_base_address. Всё равно придется делать новую функцию и учитывать это смещение. Лучше разработать новый вариант заголовка, чтобы загрузчик мог сам загружать DLL и делать связывание.
  • Всё равно придется делать новую функцию и учитывать это смещение. Лучше разработать новый вариант заголовка, чтобы загрузчик мог сам загружать DLL и делать связывание.
    ...было бы просто замечательно :)
  • У меня вопрос по DLL.Как выделять в DLL память под стек ?

    Я пишу одну DLL-ку.Она работает,если не передавать параметров через стек.А если передавать параметры через стек,то DLL не работает(глюки всякие появляются).
  • andrew_programmer
    ДЛЛ использует стек программы, так что ничего не надо выделять. Проверь передачу параметров и очистку стека после вызова, ещё лучше использовать макросы из proc32.inc ( proс, stdcall и т.д) примеры есть в исходниках ядра core/dll core/heap
  • Вот пример DLL:

    Code: Select all

    format MS COFF
    
    public EXPORTS
    
    section '.flat' code readable align 16
    
    align 4
    test_dll:
    
          pop [v2]
          pop [v1]
    
          mov eax,13
          mov ebx,20*65536+100
          mov ecx,50*65536+100
          mov edx,0xffffff
          int 0x40
    
          ret
    
    align 16
    EXPORTS:
    		dd szTest,test_dll
    		dd 0
    
    szTest		db 'test_dll',0
    
    
    section '.data' data readable writable align 16
    
    v1     rd 1
    v2     rd 1
    А вот программа,загружающая эту DLL:

    Code: Select all

    use32
    	db	'MENUET01'
    	dd	1
    	dd	start
    	dd	i_end
    	dd	0x1000
    	dd	0x1000
    	dd	0
    	dd	0
    
    start:
    	call draw_window
    
    	mov	eax, 68
    	mov	ebx, 19
    	mov	ecx, dll_name
    	int	0x40
    	test	eax,eax
    	jz	exit
    
    	mov ebx,[eax+4]
    	mov [test_dll],ebx
    
            push 1
            push 2
    
    	call [test_dll]
    
    	mov eax,5
    	mov ebx,200
    	int 0x40
    
    
    exit:
    	or	eax, -1
    	int	0x40
    
    draw_window:
    
    	mov eax,12
    	mov ebx,1
    	int 0x40
    
    	xor eax,eax
    	mov ebx,100*65536+300
    	mov ecx,100*65536+300
    	mov edx,0x03aabbcc
    	int 0x40
    
    	mov eax,12
    	mov eax,2
    	int 0x40
    
    	ret
    
    ;DATA
    dll_name db '/hd2/1/KOLIBRI/develop/testdll/dll',0
    
    align 4
    test_dll dd 0
    
    i_end:
    Код простой,но не работает.Почему - я незнаю.
  • andrew_programmer
    Не забывай что call записывает в стек адрес возврата

    pop [v2] загрузит из стека адрес возврата
    pop [v1] загрузит 2

    ret загрузит 1 и запишет ее в eip

    замени код на

    mov eax, [esp+4] ;2
    mov ebx, [esp+8], 1

    mov [v1], ebx
    mov [v2], eax

    ret замени на ret 8
    или после вызова функции добавь add esp,8
    иначе будет разрушен стек

    ещё раз рекомендую макросы из proc32.inc с их помощью можно создавать в стеке локальные переменные, что очень удобно.
  • Serge

    Большое спасибо за совет.
  • При написании DLL уже можно использовать Fast System Call's?
  • Да запросто
  • Я не понял а на SVNе лежат исходники DLLей которые есть в дистре или нет? Я чтото найти не могу.
  • Alver
    На SVN их пока что нет, но я думаю исправить эту ситуацию. Просто, это был как бы эксперимент, и я не знал, во что он выльется :)
    Сейчас их можно взять на мойм сайте: (7z|zip)
  • Здравствуйте!
    Будет ли такой DLL код работать?

    Code: Select all

    format MS COFF
    public EXPORTS
    
    section '.flat' code readable align 16
    
    _ADDNumbers@8:
    push ebp
    mov ebp, esp
    sub esp, 4
    mov dword  [ebp-4], 0
    mov eax, 100
    mov dword  [_A], eax
    mov eax, dword  [ebp+12]
    add eax, dword  [ebp+8]
    mov dword  [ebp-4], eax
    mov eax, dword  [ebp-4]
    mov esp, ebp
    pop ebp
    ret 8
    
    align 16
    EXPORTS:
    dd    szADDNumbers@8,_ADDNumbers@8
    db   0,0
    
    szADDNumbers@8   db  'ADDNumbers@8',0
    
    section '.bss' data readable writable
    align 4
            _A:   rb 4
            _C:   rb 8
            _B:   rb 12
            _D:   rb  8
    
    section '.data' data readable writable
    align 4
    _Lt_0007:       db      "Hello",0
    _Lt_0008:       dq      32768
    _Lt_000B:       db      "Hello World!",0
    
    И ещё пару вопросов, о DLL.

    Импортируемые функции - Должны обязательно находится в секции '.flat' или его можно вписать в секцию '.data' или так:

    Code: Select all

    section '.export' data readable writable
    EXPORTS:
    dd    szADDNumbers@8,_ADDNumbers@8
    db   0,0
    
    szADDNumbers@8   db  'ADDNumbers@8',0
    
    Заранее, спасибо!
  • Who is online

    Users browsing this forum: No registered users and 9 guests