Форум: "WinAPI";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];
ВнизСтранность с вызовом функции из DLL Найти похожие ветки
← →
Углук © (2007-03-05 13:47) [0]Здравствуйте!
У меня возникла следующая ситуация:
Есть проект, который вызывает функции DLL.
В функции EntryPoint, привязал к DLL_PROCESS_DETACH одну функцию.
При отладке полоска трассировки заглядывает внутрь на begin, а затем прыгает в другую функцию! Чушь какая-то, что там происходит, может кто-то сталкивался? Прилагаю код DLL:
Примечание:
Внутри эта DLL,в свою очередь вызывает еще одну DLL.
procedure RunL; stdcall;
var i: byte;
bVoltage, bSubIndex: BYTE;
w:word;
begin
AssignFile(f,"dll_log.txt");
Rewrite(f);
InitHAL();
writeln(f," "+DateTimeToStr(Now));
ActualChannels:=0;
for i:= 0 to 5 do begin
GetID(i,@bVoltage,@bSubIndex);
//GetID вызов функции еще одной DLL (трассируется нормально)
if bVoltage>0 then
begin
Inc(ActualChannels,1);
writeln(f," Active "+ IntToStr(i) + "Channel" );
end;
end;
end;
procedure CloseS; stdcall;
begin
writeln(f,DateTimeToStr(Now));
CloseFile(f);
CloseHAL();
end;
procedure EntryProc(dwReason: DWORD);
begin
case dwReason of
DLL_PROCESS_DETACH: CloseS;
end;
end;
exports CountVoltage;
exports RecountADCVoltage;
exports CountCurrent;
exports StaticChange;
exports RecountCurrent;
exports Runl;
exports CloseS;
Из процедуры CloseS "заскакивает" в RunL
← →
Сергей М. © (2007-03-05 13:50) [1]Ну а где вызывающий код ?
← →
Углук © (2007-03-05 13:53) [2]Вызывающий код (из Host проекта вышеуказанной DLL):
var
Form1: TForm1;
Hinstance1:DWORD;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Hinstance1:=LoadLibrary("Project2.dll");
RunL;
FreeLibrary(Hinstance1);
← →
Углук © (2007-03-05 13:55) [3]Да еще : замечено в процессе отладки, что напротив строки
writeln(f,DateTimeToStr(Now));
Процедуры CloseS не ставится этакая синяя точка, которая показывает, останавливается ли тут полоска трассировки
← →
Сергей М. © (2007-03-05 13:55) [4]
> DLL_PROCESS_DETACH: CloseS;
Хрень какая-то ...
Хост-приложение вызвало экп.процедуру CloseS(), при этом файл f был закрыт.
Теперь хост-приложение выгружает библ-ку, в рез-те на строчке writeln(..) осуществляется попытка обращения к УЖЕ закрытому файлу.
??
← →
Сергей М. © (2007-03-05 13:57) [5]
> Углук © (05.03.07 13:53) [2]
Что за бред ?
Где в проекте хост-приложения декларация идентификатора RunL ?
Ты что, еще и статически (!!) импортируешь RunL ?!
← →
Углук © (2007-03-05 13:57) [6]var f:textfile; объявлено в глобале. Открывается в RunL , закрывается в CloseL...типа...
← →
Углук © (2007-03-05 13:58) [7]Декларация прописана в pas файле
unit Unit2;
interface
uses Windows,Classes;
function RecountCurrent(Current:Word; Channel:byte):Extended; external "Project2.dll";
function RecountADCVoltage(Voltage:Word;Channel:byte):Extended;external "Project2.dll";
function CountVoltage(V:Extended; Channel:byte):Word;external "Project2.dll";
procedure StaticChange(Channel: byte; var NewValue:Extended); external "Project2.dll";
function CountCurrent(V:Extended; Channel:byte):Word;external "Project2.dll";
function GetStaticVoltage(Channel:byte):Extended; external "Project2.dll";
function GetStaticCurrent(Channel:byte):Extended; external "Project2.dll";
procedure RunL; external "Project2.dll";
procedure CloseL; external "Project2.dll";
implementation
end.
← →
Сергей М. © (2007-03-05 13:59) [8]
> Углук © (05.03.07 13:57) [6]
> var f:textfile; объявлено в глобале
Да фиолетово где ты объявляешь f )
Ты в вопросы вник ?
← →
Углук © (2007-03-05 14:00) [9]в хост-приложении написано
uses .....,unit2;
← →
Сергей М. © (2007-03-05 14:00) [10]
> Углук © (05.03.07 13:58) [7]
>
> Декларация прописана в pas файле
Ну и какого ж ты грузишь библ-ку дважды ?
← →
Углук © (2007-03-05 14:01) [11]чего-то я не выкупаю...
> Где в проекте хост-приложения декларация идентификатора
> RunL ?
А где ему быть?
← →
Сергей М. © (2007-03-05 14:02) [12]
> А где ему быть?
>
А как тебе нужно грузить библ-ку - динамически или статически ?
← →
Углук © (2007-03-05 14:02) [13]Динамически
← →
Сергей М. © (2007-03-05 14:03) [14]Тогда зачем
procedure КакаяТоТамПроцедура; external "Project2.dll";
??
← →
Сергей М. © (2007-03-05 14:04) [15]И где соответствие соглашений о вызовах ?
← →
Углук © (2007-03-05 14:04) [16]
> procedure КакаяТоТамПроцедура; external "Project2.dll";
А как еще можно сделать, подскажите, пожалуйста
← →
Сергей М. © (2007-03-05 14:08) [17]type
TRunL: procedure; stdcall;
var
RunL: TRunL;
..
Hinstance1:=LoadLibrary("Project2.dll");
Win32Check(Hinstance1 <> 0);
try
RunL := GetProcAddr(Hinstance1, "RunL");
finally
FreeLibrary(Hinstance1);
end;
← →
Сергей М. © (2007-03-05 14:10) [18]Hinstance1:=LoadLibrary("Project2.dll");
Win32Check(Hinstance1 <> 0);
try
RunL := GetProcAddr(Hinstance1, "RunL");
Win32Check(Assigned(RunL));
RunL; //собственно вызов
finally
FreeLibrary(Hinstance1);
end;
← →
Углук © (2007-03-05 14:19) [19]Спасибо. Но все равно не работает:)
← →
Сергей М. © (2007-03-05 14:22) [20]Приводи весь код
← →
Углук © (2007-03-05 14:24) [21]Хорошо.
Вот Dll:
library Project2;
uses SysUtils,Windows,
Classes,Math,EnergyInterface;
const
MAX_CHANNELS=6;
MAX_VOLTAGE:array [0..5] of Extended = (15.01,15.07,19.98,20.01,29.92,30.005);
MAX_ADC_VOLTAGE:array [0..5] of Extended = (15.34721,15.34155,20.37806,20.34280,30.56164,30.54950);
MAX_CURRENT:array [0..5] of Extended = (3.6,3.6,3.6,3.6,3.6,3.6);
MAX_ADC_CURRENT:array [0..5] of Extended= (4.95462,4.99168,4.9958,5.01672,4.893405,4.98753);
CURRENT_MODIFIER: array [0..5] of Extended=(-0.018,-0.016,-0.02,-0.018,-0.018,-0.018 );
VOLTAGE_MIN_STEP:array [0..5] of Extended= (0.00023,0.00023,0.0003,0.0003,0.00045,0.00045);
CURRENT_MIN_STEP:Extended=0.00244;
NBV=16;
NBI=12;
NBV_ADC=12;
TWO_RAISED_BY_NBV_ADC=4095;
TWO_RAISED_BY_NBI:DWORD =4095;
SAMPLES_PER_PERIOD =32;
TAU_DAC:Extended=66*10e-6;
TAU_DEL: Extended= 23/4*10e6;
TAU:Extended=2*10e-4; //Ïåðèîä èçìåíåíèÿ
{$R *.res}
var f:textfile;
ActualChannels:byte;
function RecountCurrent(Current:Word; Channel:byte):Extended; stdcall;
var t:DWORD;
g:DWORD;
s:extended;
begin
result:=((Current*MAX_ADC_CURRENT[Channel])/(IntPower(2,NBI)-1))-CURRENT_MODIFIER[Channel];
end;
function RecountADCVoltage(Voltage:Word;Channel:byte):Extended; stdcall;
begin
result:=(Voltage*MAX_ADC_VOLTAGE[Channel])/(IntPower(2,NBV_ADC)-1);
end;
function CountVoltage(V:Extended; Channel:byte):Word; stdcall
begin
if V>MAX_VOLTAGE[Channel] then V:=MAX_VOLTAGE[Channel];
result:=Word(Trunc((V/MAX_VOLTAGE[Channel])*(IntPower(2,NBV)-1)));
end;
procedure StaticChange(Channel: byte; var NewValue:Extended); stdcall;
var value : word;
begin
if NewValue>MAX_VOLTAGE[Channel] then NewValue:=MAX_VOLTAGE[Channel];
Enable(0);
value:=CountVoltage(Round(newValue),Channel);
writeln(f,"Óñòàíàâëèâà 29;òñÿ íàïðÿæåíèå â êàíàëå "+IntToStr(Channel)+" = " + IntToStr(value));
setVoltage(Channel,value);
end;
function CountCurrent(V:Extended; Channel:byte):Word;
begin
if V>MAX_CURRENT[Channel] then V:=MAX_CURRENT[Channel];
result:=Word(Trunc((V/MAX_CURRENT[Channel])*(IntPower(2,NBI)-1)));
end;
function GetStaticVoltage(Channel:byte):Extended; stdcall;
var wVolt,wNil,wEr:WORD;
bVolt, bNil, bEr:byte;
begin
GetOutState(Channel,@wVolt,@wNil,@bEr);
writeln(f,"Íàïðÿæåíèå â êàíàëå "+IntToStr(Channel)+" = " + IntToStr(wVolt));
result:=RecountADCVoltage(wVolt,Channel) ;
end;
function GetStaticCurrent(Channel:byte):Extended; stdcall;
var wCurr,wNil,wEr:WORD;
bEr:byte;
begin
GetOutState(Channel,@wNil,@wCurr,@bEr);
writeln(f,"Òîê â êàíàëå "+IntToStr(Channel)+" = " + IntToStr(wCurr));
result:=RecountCurrent(wCurr,Channel) ;
end;
procedure EnableAll; stdcall;
var i:byte;
begin
for i:= 0 to ActualChannels-1 do Enable(i);
end;
procedure DisableAll; stdcall;
var i:byte;
begin
for i:= 0 to ActualChannels-1 do Disable(i);
end;
procedure RunL; stdcall;
var i: byte;
bVoltage, bSubIndex: BYTE;
w:word;
begin
AssignFile(f,"dll_log.txt");
Rewrite(f);
InitHAL();
writeln(f,"Ñòàðò "+DateTimeToStr(Now));
//TestChannels;
ActualChannels:=0;
for i:= 0 to 5 do begin
GetID(i,@bVoltage,@bSubIndex);
if bVoltage>0 then
begin
Inc(ActualChannels,1);
writeln(f," Êàíàë "+ IntToStr(i) + " â íàëè÷èè" );
end;
end;
end;
procedure CloseS;
begin
writeln(f,"Çàâåðøåíèå ðàáîòû "+DateTimeToStr(Now));
CloseFile(f);
CloseHAL();
end;
exports CountVoltage;
exports RecountADCVoltage;
exports CountCurrent;
exports StaticChange;
exports RecountCurrent;
exports Runl;
exports CloseS;
begin
end.
← →
Углук © (2007-03-05 14:26) [22]Вот хост-приложение:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TRunL= procedure; stdcall;
var
RunL1: TRunL;
b:LongBool;
Form1: TForm1;
Hinstance1:DWORD;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Hinstance1:=LoadLibrary("Project2.dll");
try
RunL1:= GetProcAddress(Hinstance1, "RunL");
RunL1;
finally
b:=FreeLibrary(Hinstance1);
end;
end;
end.
← →
Сергей М. © (2007-03-05 14:26) [23]А где код хост-проекта ?
← →
Сергей М. © (2007-03-05 14:27) [24]И что "не работает" ?
← →
Leonid Troyanovsky © (2007-03-05 14:29) [25]
> Углук © (05.03.07 14:26) [22]
> RunL1:= GetProcAddress(Hinstance1, "RunL");
Runl.
Принято анализировать GetLastError.
--
Regards, LVT.
← →
Углук © (2007-03-05 14:30) [26]Не работает нормально отладка (даже в хост-приложении) и не просходит запись в файл dll_log(Хотя бы это).
← →
Сергей М. © (2007-03-05 14:31) [27]
> Углук
Имена экспортируемых процедур/ф-ций регистрочувствительны !
Runl <> RunL
← →
Сергей М. © (2007-03-05 14:32) [28]
> Углук © (05.03.07 14:30) [26]
> Не работает нормально отладка
Работает. Причем нормально.
← →
Углук © (2007-03-05 14:38) [29]Ура! заработало! Регистрочувствительность !Спасибо всем - век не забуду
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.049 c