Autor Beitrag
sourcehunter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 482

Win XP | Suse 10.1
Delphi 2005 Pers.
BeitragVerfasst: Sa 20.11.04 19:57 
Ich habe folgenden Sourcecode geschrieben:

ausblenden volle Höhe Delphi-Quelltext
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:
unit Unit1;

interface

uses
  ShareMem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, moduleman, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Manager:TModuleManager;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
   Manager:=TModuleManager.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Manager.LoadModule('J:\Programme\Borland\Delphi7\Projects\Modulmanager\TestModul.dll');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   Manager.Destroy;
end;

end.


Ich habe es mir mit dem Einzeldurchlauf angeguckt und da zeigt er mir an, dass in Zeile 42 ein Fehler auftritt. Zuerst eine ungültige Zeigeroperation, dann ein Runtime Error 217.
Kann mir jemand sagen, warum?

_________________
Linux und OpenSource rulez!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 21.11.04 00:30 
Könntest du bitte mal den Source des Modul-Managers (Unit moduleman) posten? Ansonsten muss ich mir ne Glaskugel erst leihen.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: So 21.11.04 00:36 
Ohne TModuleManager zu kennen, würde ich einfach mal darauf tippen, das es geht wenn du Manager.Destroy durch Manager.Free ersetzt.

_________________
Ciao, Sprint.
sourcehunter Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 482

Win XP | Suse 10.1
Delphi 2005 Pers.
BeitragVerfasst: Fr 17.12.04 21:38 
Wie dumm von mir den Quellcode zu vergessen. :oops:

Ich hab mich inzwischen nochmal mit dem Problem beschäftigt und habe es auf folgenden Code reduzieren können:
ausblenden volle Höhe Delphi-Quelltext
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:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
unit Unit1;

interface

uses
  ShareMem, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TFunction=function:Boolean;
  TGetFunctions=function:String;

  TPointerListElement=class
  private
     Next:TPointerListElement;
     Data:Pointer;
  public
     constructor Create;
     destructor Destroy;
     function GetNext:TPointerListElement;
     function GetData:Pointer;
     procedure SetNext(Element:TPointerListElement);
     procedure SetData(NewData:Pointer);
  end;

  TPointerList=class
  private
     First:TPointerListElement;
     Last:TPointerListElement;
  public
     constructor Create;
     destructor Destroy;
     procedure Add(Element:TPointerListElement);
  end;

  TModuleFunction=class
  private
     Name:String;
     FunctionPointer:TFunction;
  public
     constructor Create;
     destructor Destroy;
     procedure SetFunction(NewFunction:TFunction);
     procedure SetName(NewName:String);
     function GetFunction:TFunction;
     function GetName:String;
  end;

  TModule=class
  private
     Name:String;
     Functions:TPointerList;
     GetFunctions:TGetFunctions;
     Handle:THandle;
  public
     constructor Create;
     destructor Destroy;
     procedure LoadModule(Name:String);
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  NewModule:TModule;

implementation

{$R *.dfm}

function dummyfunc:Boolean;
begin
   Result:=false;
end;

function dummygetfunc:String;
begin
   Result:='';
end;

function GetWord(var s:String):String;
var buf:String;
begin
   buf:='';
   while (Length(s)>0) and (s[1]<>',') do
   begin
      buf:=buf+s[1];
      Delete(s,1,1);
   end;
   Delete(s,1,1);
   result:=buf;
end;

{TPointerListElement}

constructor TPointerListElement.Create;
begin
   inherited Create;
   Next:=nil;
   Data:=nil;
end;

destructor TPointerListElement.Destroy;
begin
   Next:=nil;
   Data:=nil;
   inherited Destroy;
end;

function TPointerListElement.GetNext:TPointerListElement;
begin
   Result:=Next;
end;

function TPointerListElement.GetData:Pointer;
begin
   Result:=Data;
end;

procedure TPointerListElement.SetNext(Element:TPointerListElement);
begin
   Next:=Element;
end;

procedure TPointerListElement.SetData(Newdata:Pointer);
begin
   Data:=NewData;
end;

{TPointerList}

constructor TPointerList.Create;
begin
   inherited Create;
   First:=nil;
   Last:=nil;
end;

destructor TPointerList.Destroy;
var buf,old:TPointerListElement;
begin
   buf:=First;
   while buf<>nil do
   begin
      old:=buf;
      buf:=buf.GetNext;
      old.Destroy;
   end;
   First:=nil;
   Last:=nil;
   inherited Destroy;
end;

procedure TPointerList.Add(Element:TPointerListElement);
begin
   if First=nil then
   begin
      First:=Element;
      Last:=Element;
   end
   else
   begin
      Last.SetNext(Element);
      Last:=Element;
   end;
end;

{TModuleFunction}

constructor TModuleFunction.Create;
begin
   inherited Create;
   FunctionPointer:=nil;
   Name:='';
end;

destructor TModuleFunction.Destroy;
begin
   FunctionPointer:=nil;
   Name:='';
   inherited Destroy;
end;

procedure TModuleFunction.SetFunction(NewFunction:TFunction);
begin
   FunctionPointer:=NewFunction;
end;

procedure TModuleFunction.SetName(NewName:String);
begin
   Name:=NewName;
end;

function TModuleFunction.GetFunction:TFunction;
begin
   Result:=FunctionPointer;
end;

function TModuleFunction.GetName:String;
begin
   Result:=Name;
end;

{TModule}

constructor TModule.Create;
begin
   inherited Create;
   Functions:=TPointerList.Create;
   GetFunctions:=nil;
   Name:='';
   Handle:=0;
end;

destructor TModule.Destroy;
begin
   FreeLibrary(Handle);
   Functions.Destroy;
   GetFunctions:=nil;
   Name:='';
   Handle:=0;
   inherited Destroy;
end;

procedure TModule.LoadModule(Name:String);
var NewElement:TPointerListElement;
    NewModuleFunction:TModuleFunction;
    functionsstring:String;
begin
   Name:='TestModul';
   Handle:=LoadLibrary(PAnsiChar('D:\programme\Borland\Delphi7\Projects\PointerList\TestModul.Dll'));
   GetFunctions:=GetProcAddress(Handle,'GetFunctions');
   functionsstring:=GetFunctions;
   NewElement:=TPointerListElement.Create;
   NewModuleFunction:=TModuleFunction.Create;
   NewModuleFunction.SetName(GetWord(functionsstring));
   NewModuleFunction.SetFunction(GetProcAddress(Handle,PChar(NewModuleFunction.GetName)));
   NewElement.SetData(NewModuleFunction);
   Functions.Add(NewElement);
end;


{TForm1}

procedure TForm1.FormCreate(Sender: TObject);
begin
   NewModule:=TModule.Create;
   NewModule.LoadModule('');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   NewModule.Destroy;
end;

end.


Der Fehler tritt immer noch nach dem Zerstören auf. Aber ich bin inzwischen so weit, dass es irgendetwas mit dem laden der DLL zu tun hat.

Ich habe dieses Modul zum Testen benutzt:
ausblenden volle Höhe Delphi-Quelltext
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:
library TestModul;

{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der
  ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt-
  Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die
  Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle
  Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die
  sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur
  Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL.
  Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String-
  Informationen als PChar- oder ShortString-Parameter übergeben. }

  

uses
  ShareMem,
  SysUtils,
  Classes,
  lists;

{$R *.res}

function Test:Boolean; stdcall;
begin
   result:=true;
end;

function GetFunctions:String;
begin
   result:='Test';
end;

exports

   GetFunctions name 'GetFunctions',
   Test name 'Test';

end.

_________________
Linux und OpenSource rulez!
Phantom1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 390



BeitragVerfasst: Fr 17.12.04 23:04 
Ich habe mich damit jetzt nich so genau befasst, aber wenn ich ein neues Project bzw Anwendung erstelle und anschließend die unit sharemem an erste stelle schreibe und das programm compiliere, genau dann tritt das gleiche problem wie bei dir auf.

EDIT:
Ach jetzt hab ich's gefunden, du musst die ShareMem unit in der DPR datei als erstes einbinden!

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
program Project1;

uses
  ShareMem,
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
sourcehunter Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 482

Win XP | Suse 10.1
Delphi 2005 Pers.
BeitragVerfasst: Sa 18.12.04 00:14 
Danke!
Funktioniert einwandfrei.

_________________
Linux und OpenSource rulez!