Toon posts:

[Delphi] DLL functie probleem

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo!
Ik heb mbv. Delphi 6 een .dll file gemaakt met een enkele (export) functie daarin. Als ik deze functie aanroep vanuit een (Delphi) programma, krijg ik de juiste gegevens in het "Usage" record.
Daarnaast heb ik een programma geschreven in Win32 API met een eigen WindowProc etc. Met dit programma (dat de units Messages en Windows gebruikt) kan ik de gegevens van het record ineens niet meer goed lezen :?

Kan iemand mij misschien met dit probleem helpen ????

Alvast hartelijk bedankt!!!

Gedeelte code van de DLL (DMain.dll):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
type
  TUsage = record
   Index: integer;
   CPU: double;
   CPUHistory: array [1..100] of double;
  end;

type
  PUsage = ^TUsage;

function GetCPUUsage (Usage: PUsage; MNCPU: Boolean): Boolean; export;
begin
 with PUsage do
  //Invullen van het Usage record met gegevens
  Index := Index + 1;
  if Index > 100 then Index := 1;
  CPU := //CPU gebruik...
  CPUHistory [Index] := CPU;
 end;
 Result := True;
end;

exports GetCPUUsage;


Gedeelte code van de Win32 application:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
type
 TGetCPUUsage = function (Usage: PUsage; MNCPU: Boolean): Boolean;

var
 GetCPUUSage: TGetCPUUSage;
 Usage: TUsage;
 HLib: THandle;

procedure LaadDll;
begin
 if HLib = 0 then
  begin
   HLib := LoadLibrary ('DMain');
   if HLib <> 0 then
    begin
     @GetCPUUsage := GetProcAddress (HLib, 'GetCPUUsage');
     if @GetCPUUsage = nil then MessageBox (0, 'Function GetCPUUsage not available in DMain.dll.', 'Error', MB_OK);
    end
    else
    begin
     MessageBox (0, 'DMain.dll not available.', 'Error', MB_OK);
    end;
  end;
end;

procedure BeeindigDll;
begin
 FreeLibrary (HLib);
 HLib := 0;
 @GetCPUUsage := nil;
end;

procedure BepaalHetCPUGebruik;
begin
 if GetCPUUsage <> nil then GetCPUUsage (@Usage, True);
end;

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

ziet er gewoon goed uit. Wat is 'kan niet meer lezen'?

Misschien stdcall of cdecl achter de function declaratie zetten voor compatebiliteit met c

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
Met "kan niet lezen" bedoel ik dat het erop lijkt dat sommige waarden in het record niet gevuld lijken te worden (terwijl dat de .dll wel doet), of op een of andere manier door de host application niet goed gelezen worden (misschien een record pointer probleem????).

De array lijkt altijd goed gelezen te worden. Als ik daarentegen bijvoorbeeld de cpu array grafisch teken (in een window) en daarbij de (usage.) cpu variabele bijhoudt komen deze totaal niet overeen.
maw: cpuhistory [index] <> cpu

Met een Delphi (TForm) applicatie daarentegen komen de gevevens van de array en het cpu veld wel overeen.
maw: cpuhistory [index] = cpu


Hieronder staat de source code van de in Win32 API geschreven host application waarmee ik de functie binnen de .dll aanroep.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
program TestProject2;

uses
  Messages,
  Windows;

{$R *.res}

type
  TMainUsage = record
   Index: integer;                  // Actuele index
   CPU: double;                     // %
   CPUMean: double;                     // %
   CPUPeak: double;                     // %
   CPUHistory: array [1..100] of double;        // 1..100 %
   NCPUCount: integer;                  // Aantal CPU
   NCPU: array [1..10] of double;           // 1..10 %
   NCPUMean: array [1..10] of double;           // 1..10 %
   NCPUPeak: array [1..10] of double;           // 1..10 %
   NCPUHistory: array [1..10, 1..100] of double;    // 1..10, 1..100 %
   Memory: double;                  // %
   MemoryUsed: integer;                 // Byte
   MemoryTotal: integer;                // Byte
   MemoryHistory: array [1..100] of double;     // 1..100 %
   Pagefile: double;                    // %
   PagefileUsed: integer;               // Byte
   PagefileTotal: integer;              // Byte
   PagefileHistory: array [1..100] of double;       // 1..100 %
  end;

type
  PMainUsage = ^TMainUsage;

type
  TGetMainUsage = function (MainUsage: PMainUsage; MNCPU: Boolean): Boolean;

var HLibMain:           THandle;
    GetMainUsage:       TGetMainUsage;
    MainUsage:          TMainUsage;
    Timer:              THandle;
    Hwnd:               THandle;

function OnPaint: Boolean;
var DC: HDC;
    PS: TPaintStruct;
    s: string;
begin
 DC := BeginPaint (Hwnd, PS);
 Str (MainUsage.Index, s);
 s := 'Index: ' + s;
 TextOut (DC, 5, 5, PChar (s), Length (s));
 Str (MainUsage.CPU : 3 : 2, s);
 s := 'CPU: ' + s + '%';
 TextOut (DC, 5, 20, PChar (s), Length (s));
 Str (MainUsage.CPUMean : 3 : 2, s);
 s := 'Mean CPU: ' + s + '%';
 TextOut (DC, 5, 35, PChar (s), Length (s));
 Str (MainUsage.CPUPeak : 3 : 2, s);
 s := 'Peak CPU: ' + s + '%';
 TextOut (DC, 5, 50, PChar (s), Length (s));
 Str (MainUsage.CPUHistory [MainUsage.Index] : 3 : 2, s);
 s := 'CPU History [Index]: ' + s + '%';
 TextOut (DC, 5, 65, PChar (s), Length (s));
 EndPaint (Hwnd, PS);
 Result := True;
end;

function WindowProc (Hwnd: THandle; Msg: integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
 case Msg of
  WM_DESTROY:begin
              postquitmessage (0);
              Result := DefWindowProc (Hwnd, Msg, wParam, lParam);
             end;
  WM_PAINT:begin
            OnPaint;
            Result := 0;
           end;
  else Result := DefWindowProc (Hwnd, Msg, wParam, lParam);
 end;
end;

procedure LoadInputLibraries;
begin
 if HLibMain = 0 then
  begin
   HLibMain := LoadLibrary ('DMain');
   if HLibMain <> 0 then
    begin
     @GetMainUsage := GetProcAddress (HLibMain, 'GetMainUsage');
     if @GetMainUsage = nil then MessageBox (0, 'Function GetMainUsage not available in DMain.dll.', 'Error', MB_OK);
    end
    else
    begin
     MessageBox (0, 'DMain.dll not available.', 'Error', MB_OK);
    end;
  end;
end;

procedure FreeInputLibraries;
begin
 if FreeLibrary (HLibMain) then
  begin
   HLibMain := 0;
   @GetMainUsage := nil;
  end; 
end;

procedure Timer1OnTimer (Handle: THandle; Msg: integer; Event: integer; Time: DWORD);
begin
 if @GetMainUsage <> nil then GetMainUsage (@MainUsage, True);
 RedrawWindow (Hwnd, nil, 0, RDW_ERASE or RDW_INVALIDATE);
end;

procedure InitializeAppl;
var WindowClass: TWndClassEx;
begin
 WindowClass.cbSize := SizeOf (TWndClassEx);
 WindowClass.style := CS_DBLCLKS or CS_HREDRAW or CS_OWNDC or CS_VREDRAW;
 WindowClass.lpfnWndProc := @WindowProc;
 WindowClass.cbClsExtra := 0;
 WindowClass.cbWndExtra := 0;
 WindowClass.hInstance := HInstance;
 WindowClass.hIcon := LoadIcon (HInstance, 'MAINICON');
 WindowClass.hCursor := LoadCursor (0, IDC_ARROW);
 WindowClass.hbrBackground := GetStockObject (WHITE_BRUSH);
 WindowClass.lpszMenuName := nil;
 WindowClass.lpszClassName := 'MyClass';
 WindowClass.hIconSm := LoadIcon (HInstance, 'SMALLICON');
 if RegisterClassEx (WindowClass) = 0 then MessageBox (0, 'Register Window Class Failed.', 'Error', MB_OK);
 Hwnd := CreateWindowEx (0, 'MyClass', 'Visual', WS_SYSMENU or WS_VISIBLE, 100, 100, 375, 300, 0, 0, hInstance, nil);
 if Hwnd = 0 then MessageBox (0, 'Create Window Failed.', 'Error', MB_OK);
 LoadInputLibraries;
 Timer := SetTimer (Hwnd, 1, 1000, @Timer1OnTimer);
end;

procedure MessageLoop;
var Msg: TMsg;
begin
 while GetMessage (Msg, 0, 0, 0) do
  begin
   TranslateMessage (Msg);
   DispatchMessage (Msg);
  end;
end;

procedure FinalizeAppl;
begin
 KillTimer (Hwnd, Timer);
 FreeInputLibraries;
end;

begin
 InitializeAppl;
 MessageLoop;
 FinalizeAppl;
end.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ik neem aan dat je die TMainUsage structure niet in de DLL ook nog eens apart defineerd? Dat hoort thuis in een losse unit die door beide gebruikte wordt.

Misschien is er een verschil tussen de alignment. Probeer anders eens
TMainUsage = packed record

en probeer het eens met GetMainUsage stdcall te maken.

We adore chaos because we like to restore order - M.C. Escher