Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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;  //&#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 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.041 c
8-1163420624
SergeyProtopopov
2006-11-13 15:23
2007.08.19
Реализация свойства stretch в компоненте TImage (D7)


1-1181570755
LSD
2007-06-11 18:05
2007.08.19
File not found: fCtrls.dcu


2-1185000805
apic
2007-07-21 10:53
2007.08.19
Всплывающие подсказки


2-1184823592
zsergey
2007-07-19 09:39
2007.08.19
Возможности Rave Reports


15-1184841211
Один
2007-07-19 14:33
2007.08.19
Вопрос





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский