Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.08.19;
Скачать: CL | DM;

Вниз

Странность с вызовом функции из 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;  //&#207;&#229;&#240;&#232;&#238;&#228; &#232;&#231;&#236;&#229;&#237;&#229;&#237;&#232;&#255;
{$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,"&#211;&#241;&#242;&#224;&#237;&#224;&#226;&#235;&#232;&#226;&#224;&#2 29;&#242;&#241;&#255; &#237;&#224;&#239;&#240;&#255;&#230;&#229;&#237;&#232;&#229; &#226; &#234;&#224;&#237;&#224;&#235;&#229; "+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,"&#205;&#224;&#239;&#240;&#255;&#230;&#229;&#237;&#232;&#229; &#226; &#234;&#224;&#237;&#224;&#235;&#229; "+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,"&#210;&#238;&#234; &#226; &#234;&#224;&#237;&#224;&#235;&#229; "+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,"&#209;&#242;&#224;&#240;&#242; "+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," &#202;&#224;&#237;&#224;&#235; "+ IntToStr(i) + " &#226; &#237;&#224;&#235;&#232;&#247;&#232;&#232;" );
end;
end;

end;

procedure CloseS;
begin
writeln(f,"&#199;&#224;&#226;&#229;&#240;&#248;&#229;&#237;&#232;&#229; &#240;&#224;&#225;&#238;&#242;&#251; "+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 вся ветка

Текущий архив: 2007.08.19;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.03 c
2-1185473507
zep
2007-07-26 22:11
2007.08.19
InvalidPointer


15-1184567041
boriskb
2007-07-16 10:24
2007.08.19
Кто-нибудь из молодых себя узнаёт?


2-1185472944
Johnnnnn
2007-07-26 22:02
2007.08.19
GXWND


15-1185117642
Kostafey
2007-07-22 19:20
2007.08.19
Чтобы клавитуру не ломать...


15-1184780234
kami
2007-07-18 21:37
2007.08.19
Перенос системы с Raid массива на 1 винт