Вопрос Как вызвать callback функцию в inno setup из c++ кода

L-e-o-N

Пользователь
Пишу небольшую библиотеку на c++.
в inno setup есть тип:
type
Код:
TCallFunction=procedure (variable:string);
и функция в библиотеке:
Код:
function LibRunFunc(var1, var2, var3, var4:string; handle:HWND, callFunc:TCallFunction):boolean; external 'LibRunFunc@files:library.dll stdcall';
Как в с++ коде принять и вызвать последний аргумент?
Заранее скажу что принять и вызвать void(*fnc)(char[]) не получилось
 
Последнее редактирование:

L-e-o-N

Пользователь
Пример в архиве
Спасибо, когда искал в интернете информацию, по этому поводу ничего подобного не нашел
Насколько я понимаю испльзование функции VirtualAlloc есть обязательным из за флага PAGE_EXECUTE_READWRITE, другие функции по выдилению памяти не пойдут?
 

Shegorat

Безумный Лорд
Администратор
Насколько я понимаю испльзование функции VirtualAlloc есть обязательным из за флага PAGE_EXECUTE_READWRITE, другие функции по выдилению памяти не пойдут?
Да, память должна быть executable, иначе получим вылет. Здесь коллбэк для функции одного аргумента. Для большего количества надо добавлять свой обработчик.
 

L-e-o-N

Пользователь
Здесь коллбэк для функции одного аргумента. Для большего количества надо добавлять свой обработчик.
Я так понимаю, под обработчиком вы имеете в виду то что находиться в масиве call1, если да то по каким правилам передавать аргументы (я вижу что первый аргумент передаеться через регистр edx, а как быть с остальными)?
И последний вопрос: зачем использовать всю эту муть с машинным кодом, если c++ позволяет делать ассемблерные вставки (правда только под 32 битные приложения)?
 

Shegorat

Безумный Лорд
Администратор
Да, обработчик в call1. Первый аргумент edx, второй в ecx, последующие на стеке, вот только порядок не помню. Вроде пушатся в стек начиная с последнего аргумента.

Ну можно и через inline asm, просто так будет компилироваться под любым компилятором. Размер кода строго фиксирован и не зависит от компилятора и его настроек
 

Shegorat

Безумный Лорд
Администратор
Это определяеться соглашением вызовов stdcall там аргументы передаються с права на лево (с последнего аргумента)
У stdcall все аргументы передаются на стеке, справа налево.
Я про fastcall забыл. В дельфи, и инке fastcall используется. Поэтому и приходится городить огород чтобы вызвать колбэк.
 

L-e-o-N

Пользователь
У stdcall все аргументы передаются на стеке, справа налево.
Я про fastcall забыл. В дельфи, и инке fastcall используется. Поэтому и приходится городить огород чтобы вызвать колбэк.
Не знаю как остальные компиляторы, но msvc разрешает использовать fastcall
 

Shegorat

Безумный Лорд
Администратор
L-e-o-N, можешь поэкспериментировать :hi:

ЗЫ У msvc, gcc и delphi разные реализации fastcall
 
Последнее редактирование:

L-e-o-N

Пользователь
ЗЫ У msvc, gcc и delphi разные реализации fastcall
Да, я уже заметил. В msvc первый аргумент идет в ecx а второй в edx (в Inno наоборот)
По этому с функцией с одним параметром только через asm
В функций с двумя и больше параметрами первые два аргумента меняються местами, а так работает
Прилагаю код (библиотека большая, потому что это debug версия)
 

Вложения

Shegorat

Безумный Лорд
Администратор
Да, я уже заметил. В msvc первый аргумент идет в ecx а второй в edx (в Inno наоборот)
В дельфи при fastcall соглашении используется 3 регистра, в порядке аргументов - eax, edx, ecx. Последующие аргументы кладутся в стек слева направо. В инке просто в первый аргумент всегда передается контекст - тот самый пресловутый eventID.
В msvc только первые два аргумента передаются в регистрах ecx, edx. Остальные аргументы передаются в стеке справа налево.
 

L-e-o-N

Пользователь
В дельфи при fastcall соглашении используется 3 регистра, в порядке аргументов - eax, edx, ecx. Последующие аргументы кладутся в стек слева направо. В инке просто в первый аргумент всегда передается контекст - тот самый пресловутый eventID.
В msvc только первые два аргумента передаются в регистрах ecx, edx. Остальные аргументы передаются в стеке справа налево.
А как быть с возвращаемым значением?
 
Последнее редактирование:
Сверху