![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите с dll разобраться!
Petr © (2005-11-24 20:50:00)В ДЛЛ функция:
procedure GetFireZone(s, vm: Double; var res : TStringList); stdcall;
var
d, rr, Q, h, h1, s1, a, b : Double;
factor1, f2, f3, tau : Double;
i :Integer;
begin
d := df(s);
rr := d/2; // находит минимально допустимое растояние для заданной площади разлива s
Q := 0;
h := hf(d,vm,r0,g);
h1 := h1f(h, d);
for i := 0 to 5 do begin
while (abs(Q - efc[i].q) > 0.9) do begin
rr := rr + 0.1; // шаг можно изменить на более меньший
s1 := s1f(rr, d);
a := af(h1,s1);
b := bf(s1);
factor1:= fv(s1, h1, a);
f2:= fh(s1, a, b);
f3:= sqrt(power(factor1,2) + power(f2,2));
tau := exp((-0.0007)*(rr - 0.5*d));
Q := ef*f3*tau; // Интенсивность теплового излучения
end;
res.add('На растоянии '+FloatToStrF(rr, ffFixed, 4, 1)+' м наблюдается '+efc[i].c); // запоминаем найденный радиус
end;
end;
Вызываю:
d := TStringList.Create;
LibHandle := LoadLibrary('MyDll.dll');
if LibHandle >= 32 then begin
@MyFunc := GetProcAddress(LibHandle,'GetFireZone');
if @MyFunc <> nil then
MyFunc(580, 0.06, d)
else ShowMessage('11');
FreeLibrary(LibHandle);
end;
ShowMessage(d.strings[1]); // ВОТ СДЕСЬ ЭКСЕПШЕН хотя d.count = 6
Digitman (2005-11-25 10:04:00) [1]потому что, скорей всего, ты нарушил условия его использования
ShareMem должен присутствовать первымв uses-списке всехзаинтересованных проектов(т.е. в dpr-файлах, а не в pas-файлах) !
Petr (2005-11-25 09:47:00) [2]Вроде работает.
А с ShareMem почему глючит?
Digitman (2005-11-25 09:42:00) [3]будет, если на этой машине будут те самые ран-тайм-пакеты, которые приложения используют в ходе работы
Petr (2005-11-25 09:40:00) [4]а потом приложение будет работать на машине где не стоит делфи?
Petr (2005-11-25 09:23:00) [5]щас попробую
Digitman (2005-11-25 09:21:00) [6]
> Petr (25.11.05 09:17) [12]
убери ShareMem везде где ты его написал, пересобери оба проекта с установленной опцией Build With Run-Time packages и не мучайся
Petr (2005-11-25 09:20:00) [7]Это возникает при подключении ShareMem
Petr (2005-11-25 09:17:00) [8]при закрытии приложения возникает ошибка?
Просто запускаеш приложение и закрываеш его - ошибка?
Как с этим быть?
'Invalid pointer operation'
Digitman (2005-11-25 09:07:00) [9]
> begin...end © (25.11.05 08:56) [10]
да, конечно ... но это особый случай ... передача single через стек оправдана тем что вызываемой ф-ции в этом случае не нужно выполнять лишние "телодвижения" - подразумевается что работа с single будет происходить в FPU, и для загрузки single-значения в FPU-стек уже все готово, в отличии от варианта когда тот же single был бы передан через РОН, что потребовало бы предварительное сохранение содержимого РОН в память для последующей загрузки значения из памяти в FPU-стек
begin...end (2005-11-25 08:56:00) [10]> Digitman © (25.11.05 08:46) [8]
> правило передачи параметров через регистры действует только
> для типов, размер которых не превышает 4 байта
Не для всех. Single передаётся через стек.
Petr (2005-11-25 08:56:00) [11]И при подключении к проекту ShareMem
при закрытии приложения возникает ошибка?
Просто запускаеш приложение и закрываеш его - ошибка?
Digitman (2005-11-25 08:46:00) [12]
> как в этой модели параметры передаются
при stdcall параметры передаются через стек справа налево (в порядке их перечисления в объявлении ф-ции), за балансировку стека ответственна сама вызываемая ф-ция
при соглашении по умолчанию первые три параметра (слева направо в порядке объявления) передаются в регистрах EAX (1-й), EDX (2-й), ECX (3-й), остальные - через стек, за балансировку стека так же как и при stdcall ответственна сама вызываемая ф-ция ... правило передачи параметров через регистры действует только для типов, размер которых не превышает 4 байта, в случае, например, с Double (8 байт) параметр передается через стек
пример передачи параметров для данного случая при соглашении по умолчанию :
var
s, vm: Double;
res: TStringList;
procedure TForm1.Button1Click(Sender: TObject);
begin
s := 1;
vm :=2;
res := Pointer(3);
asm
push dword ptr [s + 4]
push dword ptr [s]
push dword ptr [vm + 4]
push dword ptr [vm]
lea eax, res
call GetFireZone
end;
end;
Petr (2005-11-25 07:02:00) [13]А как в этой модели параметры передаются.
я просто потом процедуру вызываю ассемблером, сам параметры в стек кладу.
Задача стоит следующая
Дано ДЛЛ, имя функции, типы и значения входных параметров.
Можно ли выполнить процедуру из длл заранее ее так не объявляя
MyFunc : procedure (s, vm: Double;var res : TStringList); stdcall;
или только самому на ассемблере.
Джо (2005-11-25 06:12:00) [14]К стати, зачем тут stdcall? Нет никакого ведь смысла, лучше оставить как есть и там и там, тогда будет использоваться более быстрая модель register.
Petr (2005-11-25 05:55:00) [15]Джо пасиб :)
ShareMem
Petr (2005-11-25 05:52:00) [16]Не-а не имею
MyFunc : procedure (s, vm: Double;var res : TStringList); stdcall;
Юрий Зотов (2005-11-25 05:38:00) [17]И еще - как объявлена переменная MyFunc? Если в DLL стоит stdcall, то и в EXE она быть объявлена так же.
======================
PS
Петр, Вы к ВНИИПО отношения не имеете, часом?
Джо (2005-11-25 05:28:00) [18]Петр, когда создаешь проект с новым DLL, среда в самом начале файла пишет длиннющий комментарий... Вы его читали?
Petr (2005-11-25 05:20:00) [19]Может TStringList как-то по-другому передавать нужно?