Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wiedermal C++ nach Delphi (https://www.delphipraxis.net/39133-wiedermal-c-nach-delphi.html)

goose33 29. Jan 2005 10:40


Wiedermal C++ nach Delphi
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallöchen,

also forlgendes Problem:

Ich brauche ein Modul für den FS2002/04 von Microsoft, wird ja jeder kennen.
Diese Module werden als *.dll geschrieben und dann nur in das Modules verzeichnis
vom FS kopiert und das wars. Die laufen dann direkt mit wenn der FS läuft.

So, ich habe nun den Code für so eine DLL in C++ hier, brauch das ganze aber unbedingt als
Delphi. Ich hab mir schon die Zähne ausgebissen daran, leider ohne Erfolg.
Was ich herausbekommen habe ist welche variable wie deklariert werden muss, aber das is auch schon fast alles.
Hier mal die grössten meiner Probleme:

Code:
typedef struct _MODULE_IMPORT {
   struct {
      int fnID;
      PVOID fnptr;
   } IMPORTSentry;
   struct {
      int fnID;
      PVOID fnptr;
   } nullentry;
} MODULE_IMPORT;
So, "struct" is doch in Delphi ein Record ja.Aber wie kann ich denn
innerhalb eines Records noch einen declarieren ??? ( IMPORTSentry und nullentry )

Dann das hier:

Code:
void FSAPI module_init(void) {}
...aber ich glaube das muss in Delphi dann so aussehen :

Code:
procedure module_init;stdcall;
begin
end;
oder lieg ich da falsch?

Jetzt kommt aber noch was wichtiges :

Code:
DLLEXPORT MODULE_LINKAGE Linkage = {
   0x00000000,
   module_init,
   module_deinit,
   0,
   0,
   0x0900,   // FS2004 version (use 0x0800 for FS2002)
   NULL
};
Damit weiss ich bis jetzt noch nicht wirklich was anzufangen und wie
ich 0x0900 als variablenwert eingeben soll weiss ich auch nicht?
Ich weiss nicht mal was ich da nehmen muss, dene aber cardinal wäre da richtig oder?
Leider mecker t Delphi immer wenn ich dann so nen wert ( 0x0900 ) verwenden will ????

Ich häng die beiden Dateien mal hier dran, vielleicht hat jemand erbarmen mit mir und schaut sich das ganze mal an, denn das is wirklich wichtig.
Ach so, noch was: Warum meckert delphi immer, wenn ich ne *.dll compilieren will rum von wegen ich solle irgendeine Host anwendung auswählen ???

So, ich danke Euch schon mal für die Hilfe !!

Matthias

malo 29. Jan 2005 11:42

Re: Wiedermal C++ nach Delphi
 
Zitat:

So, "struct" is doch in Delphi ein Record ja.Aber wie kann ich denn
innerhalb eines Records noch einen declarieren ??? ( IMPORTSentry und nullentry )
Indem du ein ganen ganz neuen Record erstellst, den du dann von dem anderen ableitest. Etwa so:

Delphi-Quellcode:
type ImportSentry = record (_Module_Import)
;)

Robert Marquardt 29. Jan 2005 14:38

Re: Wiedermal C++ nach Delphi
 
malo, das ist Unsinn.
Delphi-Quellcode:
type
  TIMPORTSentry = packed record
    fnID: Integer;
    fnptr: Pointer;
  end;

  MODULE_IMPORT = packed record
    IMPORTSentry: TIMPORTSentry;
    nullentry: TIMPORTSentry;
  end;
Das "packed" ist allerdings nur geraten.

Das Problem mit "Linkage" kann ich dir hier nicht loesen, da dies eine initialisierte Variable ist.
Es fehlt da aber Source um das korrekt zu uebersetzen. 0x0900 = $0900.

OregonGhost 29. Jan 2005 15:26

Re: Wiedermal C++ nach Delphi
 
Du hast doch die Definition von MODULE_LINKAGE:
Code:
typedef struct _MODULE_LINKAGE {
   int ModuleID;
   void (FSAPI *ModuleInit)(void);
   void (FSAPI *ModuleDeinit)(void);
   UINT32 ModuleFlags;
   UINT32 ModulePriority;
   UINT32 ModuleVersion;
   PVOID ModuleTable;
} MODULE_LINKAGE;
Das da:
Code:
DLLEXPORT MODULE_LINKAGE Linkage = { 
   0x00000000,
   module_init,
   module_deinit,
   0,
   0,
   0x0900,  // FS2004 version (use 0x0800 for FS2002)
   NULL
};
ist die Initialisierung einer Variablen vom Typ MODULE_LINKAGE, die Zuordnung ist hier zu sehen.

Kernel32.DLL 29. Jan 2005 19:51

Re: Wiedermal C++ nach Delphi
 
Zitat:

Zitat von goose33

Code:
DLLEXPORT MODULE_LINKAGE Linkage = {
   0x00000000,
   module_init,
   module_deinit,
   0,
   0,
   0x0900,   // FS2004 version (use 0x0800 for FS2002)
   NULL
};
Damit weiss ich bis jetzt noch nicht wirklich was anzufangen und wie
ich 0x0900 als variablenwert eingeben soll weiss ich auch nicht?
Ich weiss nicht mal was ich da nehmen muss, dene aber cardinal wäre da richtig oder?
Leider mecker t Delphi immer wenn ich dann so nen wert ( 0x0900 ) verwenden will ????

also:

das hier

Code:
0x0900
sieht in Delphi so aus:

Code:
$0900
Zitat:

Zitat von goose33
Ach so, noch was: Warum meckert delphi immer, wenn ich ne *.dll compilieren will rum von wegen ich solle irgendeine Host anwendung auswählen ???

Weil Delphi schlecht eine DLL starten kann. Hast du schonmal versucht, eine DLL via Doppelklick auszuführen? Eben, es geht nicht. Damit man die DLL also testen kann, gibt man Delphi einfach den Pfad zur Exe, die zu der DLL gehört. Voilà, jetzt kann die DLL getestet werden.

goose33 30. Jan 2005 21:05

Re: Wiedermal C++ nach Delphi
 
Hallöchen,

nachdem ich mir in einigen Foren und auch per Meil schon hab helfen lassen bin ich ein bischen weiter. Hier mal der jetzige code als überblick.

Code:
uses
  SysUtils, Classes;

type
    TIMPORTSentry = record
      fnID : LongInt;
      fnptr : pointer;
    end;
    Tnullentry = record
      fnID : LongInt;
      fnptr : pointer;
    end;

  MODULE_IMPORT = record
     IMPORTSentry : TIMPORTSentry;
     nullentry : Tnullentry;
  end;

  TModuleInit = procedure;stdcall;
  TModuleDeinit = procedure;stdcall;

  MODULE_LINKAGE = record
     ModuleID : LongInt;
     ModuleInit : ^TModuleInit;
     ModuleDeinit : ^TModuleDeinit;
     ModuleFlags : cardinal;
     ModulePriority : cardinal;
     ModuleVersion : cardinal;
     ModuleTable : pointer;
  end;



{$R *.res}

procedure ImportTable;stdcall;
var
  IMPORTSentry : TIMPORTSentry;
  nullentry : Tnullentry;
begin
  IMPORTSentry.fnID := 0;
  IMPORTSentry.fnptr := 0;

  nullentry.fnID := 0;
  nullentry.fnptr := 0;
end;

procedure Linkage;cdecl;
var
  TMODULE_LINKAGE:MODULE_LINKAGE;
  ModuleInit : TModuleInit;
  ModuleDeinit : TModuleDeinit;
begin
  TMODULE_LINKAGE.ModuleID := 0;
  TMODULE_LINKAGE.ModuleInit := @ModuleInit;
  TMODULE_LINKAGE.ModuleDeinit := @ModuleDeinit;
  TMODULE_LINKAGE.ModuleFlags := 0;
  TMODULE_LINKAGE.ModulePriority := 0;
  TMODULE_LINKAGE.ModuleVersion := $0900;
  TMODULE_LINKAGE.ModuleTable := 0;
end;

exports
  Linkage,ImportTable;

begin
end.
Allerdings meckert der Flugsimulator immer wenn ich die DLL verwenden will.

Hier mal noch die Mail von jemanden der auch ein Modul erstellt hat, allerdings eben auch nur in C++.:

Zitat:

Well, i dont know the Delphi language, as a result i cannt give you a source
code sample of the module. But for let the Flight simulator to read your
*.dll, you need to define two structures type:

MODULE_IMPORT and MODULE_LINKAGE

inside the MODULE_IMPORT, there must be two structures:

IMPORTSentry and nullentry

A) inside the IMPORTSentry structure, there must be two members:

1) a variable called "fnID" as "LONG" type
2) a pointer called "fnptr" as a pointer to any kind of data in memory
(void*)

B) inside the the nullentry structure, there must be two members:

1) a variable called "fnID" as "LONG" type
2) a pointer called "fnptr" as a pointer to any kind of data in memory
(void*)

inside the MODULE_LINKAGE, there must be 7 members:

A) a variable called "ModuleID" as "LONG" type
B) a pointer to a subroutine (with a _stdcall convention) called
"ModuleInit", that doesnt needs any parameter
C) a pointer to a subroutine (with a _stdcall convention) called
"ModuleDeinit", that doesnt needs any parameter
D) a variable called "ModuleFlags" as "UNSIGNED LONG" type
E) a variable called "ModulePriority" as "UNSIGNED LONG" type
F) a variable called "ModuleVersion" as "UNSIGNED LONG" type
G) a pointer called "ModuleTable" as a pointer to any kind of data in memory
(void*)

NOW after that, you need to add two subroutines (using the _stdcall
convention) in your main source code file, those subroutines must have the
names: "module_init" and the other "module_deinit", each one doesnt returns
obviously any value (so they are subroutines), and also both doesnt needs
any parameters to be passed to them.

in C language they are like:

void _stdcall module_init(void) {}
void _stdcall module_deinit(void) {}


NOW after adding those subroutines, you need to export two variables, and at
same time define theirs values:

1) one of them called "ImportTable" as "MODULE_IMPORT" type

this one must have the following values in each structure:

IMPORTSentry
---> fnID = 0
---> fnptr = 0 // NULL

nullentry
---> fnID = 0
---> fnptr = 0 // NULL

2) the another one called "Linkage" as "MODULE_LINKAGE" type

this one must have the following values for each member:

ModuleID = 0
module_init // (this is the subroutine we added before)
module_deinit // (this is the other subroutine)
ModuleFlags = 0
ModulePriority = 0
ModuleVersion = 0x0900 // FS2004 version (use 0x0800 for FS2002)
ModuleTable = 0 // NULL


NOW, you are DONE!, that's will allow the Flight Simulator to load your
module (*.dll), when the Flight Simulator loads your module (REMMEMBER, YOUR
MODULE'S ENTRY POINT FUNCTION...in C language it is commonly called
"DllMain"), you MUST hook your module to the main Flight Simulator's window
procedure, the classname of the main window is "FS98MAIN", find that window,
then using the "SetWindowLong" function define a new window procedure and
retrieve the HANDLE of the original FLIGHT SIMULATOR'S window procedure,
that should let you intercept the Flight Simulator's main window's message,
so then you can process each message before the Flight Simulator itself,
then AFTER YOUR NEW WINDOW PROCEDURE FUNCTION receives and process the
message, YOU MUST REDIRECT the window messages to the ORIGINAL FLIGHT
SIMULATOR's window procedure use the function "CallWindowProc"
Ich weiss nicht genau ob ich diese Zeilen richtig habe ?

module_init // (this is the subroutine we added before)
module_deinit // (this is the other subroutine)

Vielleicht kann ja doch nochmal jemand schauen ob das so hinhauen könnte ?

Vielen Dank
Matthias

Kernel32.DLL 30. Jan 2005 21:34

Re: Wiedermal C++ nach Delphi
 
Code:
Allerdings meckert der Flugsimulator immer wenn ich die DLL verwenden will.
Was genau meckert er denn?

goose33 30. Jan 2005 21:52

Re: Wiedermal C++ nach Delphi
 
Hallo,

naja, der sagt nur das das Modul welches geladen werden soll fehlerhaft ist.
Ich weiss nicht ob Du den Microsoft Flugsimulator 2004 kennst.
Da kann man per Modul ( *.dll ) AddOn`s programmieren. Die
DLL wird dann nur ins Modules Verzeichnis kopiert und dann
wird die DLL beim Starten des FlugSim eben mitgeladen.

Zweck meiner DLL ist eine Art Flugrekorder. Erstes Ziel ist erst mal die dll zum
laufen zu bekommen und einen neuen Menü Eintrag in das vorhanden
FlugSim Menü zu integrieren. ( btw erst mal das er nicht mehr meckert )

Wenn das erst mal gehen würde wär ich endlich einen kleinen schritt weiter.

Matthias

Kernel32.DLL 30. Jan 2005 21:56

Re: Wiedermal C++ nach Delphi
 
Zitat:

Zitat von goose33
Ich weiss nicht ob Du den Microsoft Flugsimulator 2004 kennst.

Doch, ich kenne ihn. Hatte ihn mir zugelegt, nachdem ich den Entschluss gefasst hatte, nach dem ABI zur DFS zu gehen.

Ich seh' mir den Source mal morgen an, wenn bis dahin noch niemand geantwortet hat.

goose33 30. Jan 2005 22:15

Re: Wiedermal C++ nach Delphi
 
Hallo,

da wär ich Dir echt dankbar !
Ich mach jetzt auch erst mal schicht für heute, das bringt sonst nix mehr.
Hier aber mal noch die komplette Mail von dem der das andere modul geschrieben hatte:

Zitat:

Well, i dont know the Delphi language, as a result i cannt give you a source
code sample of the module. But for let the Flight simulator to read your
*.dll, you need to define two structures type:

MODULE_IMPORT and MODULE_LINKAGE

inside the MODULE_IMPORT, there must be two structures:

IMPORTSentry and nullentry

A) inside the IMPORTSentry structure, there must be two members:

1) a variable called "fnID" as "LONG" type
2) a pointer called "fnptr" as a pointer to any kind of data in memory
(void*)

B) inside the the nullentry structure, there must be two members:

1) a variable called "fnID" as "LONG" type
2) a pointer called "fnptr" as a pointer to any kind of data in memory
(void*)

inside the MODULE_LINKAGE, there must be 7 members:

A) a variable called "ModuleID" as "LONG" type
B) a pointer to a subroutine (with a _stdcall convention) called
"ModuleInit", that doesnt needs any parameter
C) a pointer to a subroutine (with a _stdcall convention) called
"ModuleDeinit", that doesnt needs any parameter
D) a variable called "ModuleFlags" as "UNSIGNED LONG" type
E) a variable called "ModulePriority" as "UNSIGNED LONG" type
F) a variable called "ModuleVersion" as "UNSIGNED LONG" type
G) a pointer called "ModuleTable" as a pointer to any kind of data in memory
(void*)

NOW after that, you need to add two subroutines (using the _stdcall
convention) in your main source code file, those subroutines must have the
names: "module_init" and the other "module_deinit", each one doesnt returns
obviously any value (so they are subroutines), and also both doesnt needs
any parameters to be passed to them.

in C language they are like:

void _stdcall module_init(void) {}
void _stdcall module_deinit(void) {}


NOW after adding those subroutines, you need to export two variables, and at
same time define theirs values:

1) one of them called "ImportTable" as "MODULE_IMPORT" type

this one must have the following values in each structure:

IMPORTSentry
---> fnID = 0
---> fnptr = 0 // NULL

nullentry
---> fnID = 0
---> fnptr = 0 // NULL

2) the another one called "Linkage" as "MODULE_LINKAGE" type

this one must have the following values for each member:

ModuleID = 0
module_init // (this is the subroutine we added before)
module_deinit // (this is the other subroutine)
ModuleFlags = 0
ModulePriority = 0
ModuleVersion = 0x0900 // FS2004 version (use 0x0800 for FS2002)
ModuleTable = 0 // NULL


NOW, you are DONE!, that's will allow the Flight Simulator to load your
module (*.dll), when the Flight Simulator loads your module (REMMEMBER, YOUR
MODULE'S ENTRY POINT FUNCTION...in C language it is commonly called
"DllMain"), you MUST hook your module to the main Flight Simulator's window
procedure, the classname of the main window is "FS98MAIN", find that window,
then using the "SetWindowLong" function define a new window procedure and
retrieve the HANDLE of the original FLIGHT SIMULATOR'S window procedure,
that should let you intercept the Flight Simulator's main window's message,
so then you can process each message before the Flight Simulator itself,
then AFTER YOUR NEW WINDOW PROCEDURE FUNCTION receives and process the
message, YOU MUST REDIRECT the window messages to the ORIGINAL FLIGHT
SIMULATOR's window procedure use the function "CallWindowProc"

Well, that's all i can do for you to help, i cannt do beyond this, because i
dont know the syntaxis and the rules of the Delphi language.

Ich hoffe das hilf noch ein bischen....ich komm einfach nicht mehr weiter :-(

Bis morgen dann
Matthias


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:10 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz