Новые открытия! Несуществующий модуль - бага или фишка?
|
|
electrik | Дата: Среда, 06.04.2022, 22:28 | Сообщение # 1 |
Полковник
Группа: Друзья
Сообщений: 182
Статус: 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:
И всё, 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
Статус: Offline
| Я попробовал компилировать так:
Цитата fbc -dll testdll.bas -m DllMain
все нормально работает.
Так же работает твой вариант с несуществующим модулем , но этому поводу я ничего сказать не могу , попросту не знаю.
Компилировал с последней версией 1.09 32-bit и 64-bit.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
electrik | Дата: Четверг, 07.04.2022, 20:25 | Сообщение # 3 |
Полковник
Группа: Друзья
Сообщений: 182
Статус: 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
Статус: Offline
| А ну да , че то я тут затупил. Документация походу верная и чисто логически так и должно работать (как описано в документации) , но не работает. Ты же вроде регился там? Ну так создай тему , может поправят этот баг к следующему релизу.
Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
|
|
| |
electrik | Дата: Пятница, 08.04.2022, 21:18 | Сообщение # 5 |
Полковник
Группа: Друзья
Сообщений: 182
Статус: Offline
| Ещё не зарегался.
|
|
| |
zamabuvaraeu | Дата: Суббота, 09.04.2022, 14:46 | Сообщение # 6 |
Подполковник
Группа: Друзья
Сообщений: 149
Статус: 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
Статус: Offline
| А это тоже способ. Спасибо. Тем более, если я буду использовать рантайм, лучше его инициализировать.
|
|
| |