FreeBasic
Главная
Вход
Регистрация
Вторник, 15.10.2024, 15:30Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Новые открытия! Несуществующий модуль - бага или фишка?
electrikДата: Среда, 06.04.2022, 22:28 | Сообщение # 1
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
Всю жизнь я знал от компилятора, что если сделать dll с функцией DllMain, он будет ругаться, что такая функция уже объявлена. Причём, #undef тут не помогает. Раньше мне нравилось делать маленькие бинарники, я не любил юзать встроенные функции Fb и использовал WinApi. Ну а там всё можно, компилировать без RTL и соответственно указать любую точку входа в DLL. Сейчас мне надоело быть умным, надоело страдать фигнёй, и я решил прийти к DllMain при использовании RTL. Всегда меня смущал один ключик -m - указание первого модуля. Покурив, я попробовал его использовать, но всё тщетно, компилятор так же ругается: dll.asm:29: Error: symbol `_DllMain@12' is already defined. Учёл их предупреждение насчёт регистрозависимости.
Но если указать не существующий модуль, компилятор не выдаёт ошибок, и оно прокатывает.
Dll.bas:

Код
#include "windows.bi"

function DllMain alias "DllMain"(byval hinstDLL as HINSTANCE, byval fdwReason as DWORD, byval lpvReserved as LPVOID) as BOOL
print "this is DllMain"
      function = 1
      end function

sub  test alias "test"() export
print "This is test sub"      
end sub


Файл test.bas:

Код
declare sub test lib "testdll.dll" alias "test"()
test()


Компилируем dll:

Код
fbc -dll -m testdll Dll.bas


На выходе получаем testdll.dll.
Компилируем test.bas:

Код
fbc test.bas


И всё, DllMain работает!
Я знаю про конструкторы и деструкторы модулей, но мне для регистрации COM объекта нужно получить имя Dll по её хендлу. Как я понимаю, другими способами это сделать нельзя, вот я и уцепился за DllMain.
В таком случае, из Dll исчезает штатный DllMain, со всеми входящими в него main, _fb_Init и т.д.
Штатный dll:

Код

  .intel_syntax noprefix

.section .text
.balign 16

.globl _DllMain@12
_DllMain@12:
push ebp
mov ebp, esp
sub esp, 4
mov dword ptr [ebp-4], 0
.L_0004:
mov dword ptr [ebp-4], 1
cmp dword ptr [ebp+12], 1
jne .L_0006
push 0
push 0
call _main
add esp, 8
.L_0006:
.L_0005:
mov eax, dword ptr [ebp-4]
mov esp, ebp
pop ebp
ret 12
.balign 16

.globl _test@0
_test@0:
.L_011A:
push 1
push 16
push offset _Lt_011C
call _fb_StrAllocTempDescZEx@8
push eax
push 0
call _fb_PrintString@12
.L_011B:
ret
.balign 16
_main:
push ebp
mov ebp, esp
and esp, 0xFFFFFFF0
sub esp, 12
mov dword ptr [ebp-4], 0
call ___main
push 0
push dword ptr [ebp+12]
push dword ptr [ebp+8]
call _fb_Init@12
.L_0002:
.L_0003:
mov eax, dword ptr [ebp-4]
mov esp, ebp
pop ebp
ret

.section .data
.balign 4
_Lt_011C:    .ascii    "This is test sub\0"

.section .drectve
    .ascii " -export:test@0"


Незнаю, к чему это приведёт, будем ковырять.
Главное, чтобы не повлияло на RTL.
 
haavДата: Четверг, 07.04.2022, 05:06 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
Я попробовал компилировать так:

Цитата
fbc -dll testdll.bas -m DllMain


все нормально работает.

Так же работает твой вариант с несуществующим модулем , но этому поводу я ничего сказать не могу , попросту не знаю.

Компилировал с последней версией 1.09 32-bit и 64-bit.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
electrikДата: Четверг, 07.04.2022, 20:25 | Сообщение # 3
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
Ну а тут получается, у тебя в модуле DllMain что-то есть или нет? Просто как у них написано в документации, имя модуля нужно указывать два раза, как bas файл и как имя главного модуля. К примеру, если у меня файл называется testdll.bas, так я должен сделать так: fbc -dll testdll.bas -m testdll, но компилятор тогда ругается на DllMain. А так получается,что fbc -dll testdll.bas -m DllMain, это всё тот же не существующий модуль. Или я не понимаю документацию, или у них путаница какая-то.
 
haavДата: Четверг, 07.04.2022, 21:38 | Сообщение # 4
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
А ну да , че то я тут затупил. Документация походу верная и чисто логически так и должно работать (как описано в документации) , но не работает. Ты же вроде регился там? Ну так создай тему , может поправят этот баг к следующему релизу.

Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
electrikДата: Пятница, 08.04.2022, 21:18 | Сообщение # 5
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
Ещё не зарегался.
 
zamabuvaraeuДата: Суббота, 09.04.2022, 14:46 | Сообщение # 6
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline
Вот пример с собственной DLLMAIN, рантаймом фрибесика и без ассемблерных вставок:
Код
#include once "windows.bi"

' Си рантайм
Declare Function __main Alias "__main"() As Long

' Инстанция DLL
Dim Shared DllModuleHandle As HMODULE

Function MyDllMain Alias "MyDllMain"( _
        ByVal hinstDLL As HINSTANCE, _
        ByVal fdwReason As DWORD, _
        ByVal lpvReserved As LPVOID _
    )As BOOL
    
    Select Case fdwReason
        
        Case DLL_PROCESS_ATTACH
            ' Сохраняем инстанцию модуля DLL
            ' Иначе получить его будет сложно
            ' Этот HMODULE понадобится когда нужно будет получить
            ' путь к DLL файлу функцией GetModuleFileName
            DllModuleHandle = hinstDLL
            
            ' Необходимо инициализировать
            ' статические библиотеки CRT
            __main()
            
            ' И рантайм фрибейсика
            fb_Init(0, NULL, 0)
            
        Case DLL_THREAD_ATTACH
            
        Case DLL_THREAD_DETACH
            
        Case DLL_PROCESS_DETACH
            
    End Select
    
    Return True
     
End Function


Компилировать для x86 так:
Код
fbc -dll -Wl "-e _MyDllMain@12" "testdll.bas"


Для x64 убираем искажение имён:

Код
fbc -dll -Wl "-e MyDllMain" "testdll.bas"

Остальное вы знаете.
 
electrikДата: Понедельник, 11.04.2022, 18:11 | Сообщение # 7
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
А это тоже способ. Спасибо. Тем более, если я буду использовать рантайм, лучше его инициализировать.
 
  • Страница 1 из 1
  • 1
Поиск: