Freunde, Römer, Landleute,
händeringend wende ich mich an die Gemeinde.
Umgebung: Win XP unter Verwendung von Delphi 2009
Situation wie folgt:
Ich habe eine EXE und eine
DLL. Die
DLL besitzt eine TForm, die von der EXE dann und wann aufgerufen wird. Die
DLL selbst wird dynamisch aufgerufen.
Zum Aufruf möchte ich einige Parameter übergeben, die ich in einem Record zusammengefasst habe. Der Record selbst enthält andere Records wie z.B. TRect usw. Einige Typen habe ich schon mal ausgeklammert, wie z.B. die TFonts und auch die PChars. Mehr dazu später.
Problem nun:
Ich übergebe die Daten in der Exe an den Record (geprüft und korrekt). Sende diese Daten an die
DLL und es kommt zu 30% Schrott an. Ein Teil der Daten ist korrekt, ein Teil nicht. Dabei sind nicht die Datentypen oder Variable das Problem. Ein Teil von THSBColor (Tripel wie
RGB) wird korrekt übergeben ein anderer nicht.
Seltsam nur, dass der Aufruf einzelner Variable viele Male funktioniert hat. Auch in Kombination. Nun zum ersten Mal als Record gebunden hakt es. Frage nun – warum kommt ein Teil korrekt an, der andere nicht? Warum kann ich keine Font übergeben? Ich hab auch ne andere Lösung die funktioniert, aber ich wüsste es trotzdem gerne. 3. Warum kann ich meine Strings nicht mehr wie üblich (nach Umwandlung zu PWidechar) verschicken? Außerhalb des Records geht es doch. Aber wer will schon nen Procedure-Aufruf mit 30 einzelnen Parametern
Ich habe auch schon probiert, das ganze als Pointer zu verschicken. Das Ergebnis war noch schlimmer. Im dümmsten Fall würde ich einfach vermuten, dass ich eine kleine Anweisung wie Speicherreservierung oder so vergessen habe. So oder so, ich komm nicht drauf.
Definition des zu übergebenden Record
Code:
Unit Bla; (wird von EXE sowie
DLL verwendet)
Type TGlobalInfo = Record
SurfaceStyle : TSurfaceStyle;
SubRect : TRect;
HSB : THSBColor;
FHSB : THSBColor;
// AFont : TFont;
// BFont : TFont;
// CFont : TFont;
AFontColor : THSBColor;
BFontColor : THSBColor;
CFontColor : THSBColor;
// ProgDrive : PChar; // Installations-LW
// ProgPath : PChar; // Pfad des Programmes
sCurrent : Integer; // Nummer des aktuellen Satzes
sCount : Integer; // Anzahl aller Sätze
End;
__________________________________________________ __________________________________________________ _
Die Bibliothek
Code:
Library BlaBla;
Uses WinShow;
Exports ShowWindow;
End;
der Teil, der die TForm aufruft und erzeugt
Code:
Unit WinShow;
…
Procedure ShowWindow (MyInfo : TMyInfo); stdCall;
….
Procedure ShowWindow (MyInfo : TMyInfo); stdCall;
Begin
TMyDLLForm:= TMyDLLForm.Create(NIL);
Try
With TMyDLLForm Do
Begin
SurfaceStyle := MyInfo.SurfaceStyle;
SubRect := MyInfo.SubRect;
BoundsRect := SubRect;
HSB := MyInfo.HSB;
FHSB := MyInfo.FHSB;
// AFont := MyInfo.AFont;
// BFont := MyInfo.BFont;
// CFont := MyInfo.CFont;
IconFontColor := MyInfo.IconFontColor;
AFontColor := MyInfo.AFontColor;
ButtonFontColor := MyInfo.ButtonFontColor;
BFontColor := MyInfo.BFontColor;
CFontColor := MyInfo.CFontColor;
StatusFontColor := MyInfo.StatusFontColor;
// ProgDrive := MyInfo.ProgDrive;
// ProgPath := MyInfo.ProgPath;
sCurrent := MyInfo.sCurrent;
sCount := MyInfo.sCount;
ShowModal;
End;
Finally
TMyDLLForm.Release;
End;
End;
procedure TMyDLLForm.FormCreate(Sender: TObject);
begin
AFont := TFont.Create;
BFont := TFont.Create;
CFont := TFont.Create;
end;
nun noch der Part, der die EXE betrifft.
Code:
//Interface
Type TShowWindow = Procedure (Value : TMyInfo);
procedure TMyForm.MyButtonClick(Sender: TObject);
Var Funktion : TShowWindow;
GI : TMyInfo;
Handle : THandle;
PVar : PChar;
Begin
// SubUnit öffnen
Begin
GI.SurfaceStyle := MyForm.SurfaceStyle;
GI.SubRect := MyForm.SubRect;
GI.FHSB := MyForm.FHSB;
GI.HSB := MyFormMyForm.HSB;
// GI.AFont := MyForm.AFont;
// GI.BFont := MyForm.BFont;
// GI.CFont := MyForm.CFont;
GI.AFontColor := MyForm.AFontColor;
GI.BFontColor := MyForm.BFontColor;
GI.CFontColor := MyForm.CFontColor;
// PVar := StrNew(PChar(MyForm.ProgDrive));
// GI.ProgDrive := PVar;
// SysUtils.StrDispose(PVar);
// PVar := StrNew(PChar(MyForm.ProgPath));
// GI.ProgPath := PVar;
// SysUtils.StrDispose(PVar);
GI.sCurrent := GetsCurrent;
GI.sCount := GetsCount;
// Aufruf der
DLL
Handle := LoadLibrary(BlaBla.Dll');
if
Handle <> 0 then
Try
Funktion := GetProcAddress(
Handle, 'ShowWindow');
if Assigned(Funktion) then
begin
Funktion (GI);
end;
Except
FreeLibrary(
Handle);
end;
End;
end;
end;