Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Unerlaubte Member-Variablen im Service? (https://www.delphipraxis.net/9314-unerlaubte-member-variablen-im-service.html)

Phoenix 23. Sep 2003 17:32


Unerlaubte Member-Variablen im Service?
 
Hallo,

folgendes Problem:

Ich habe ein Klasse und einige Methoden darauf. Eine dieser Methoden übergebe ich nun an den ServiceControlDispatcher um den Dienst zu starten. In dieser übergebenen Methode will bzw. muss ich aber weiterhin auf member-Variablen meines Objektes zugreifen können. In dem Augenblick in dem ich aber auf ein Element der Klasse zugreifen will (ausser einem anderen Methodenaufruf) schmiert mir der Service mit einer Zugriffsverletzung ab.

Etwas anschaulicher:

Delphi-Quellcode:
   PhService = class
      // Private declarations
      private
         m_name: string;
                  [...]
      private
         procedure doStart;
         procedure servicehandler(a_val: integer); stdcall;
         procedure serviceProc(a_dwargc: integer; a_lpszargv: PChar); stdcall;
      // Proteced declarations
      protected
         procedure service_main; virtual;         protected
         property myName: string read m_name write m_name;
      // Constructor / Destructor
                  [...]
      // Public declarations
      public
         procedure Start;
      public
         property Mode: integer read m_startupmode write m_startupmode;
         property Silent: boolean read m_silent write m_silent;
   end;
Delphi-Quellcode:
procedure PhService.doStart;
begin;
   doDebugOutput('doStart');
   m_dispatcher.lpServiceName := PChar(myName);
   m_dispatcher.lpServiceProc := @PhService.serviceProc; // <-- hier wird die kommende Methode übergeben
   doDebugOutput('Start Dispatcher');
   StartServiceCtrlDispatcher(m_dispatcher); // <-- hier die Übergabe und der Start der Methode
end;


// controls the service execution
//
procedure PhService.serviceProc(a_dwargc: integer; a_lpszargv: PChar);
var
   l_name: AnsiString;
begin
   doDebugOutput('begin ServiceProc ' + m_Name); // <-- hier wird auf die Membervariable zugegriffen: Exception!
   m_statushandle := RegisterServiceCtrlHandler(PChar(m_name),
                                                @PhService.ServiceHandler);
   doDebugOutput('has ServiceController');
   if (m_statusHandle <> 0) then
   begin
      ZeroMemory(@m_status, SizeOf(m_status));
      with m_status do
      begin
         dwServiceType := SERVICE_WIN32_OWN_PROCESS;
         dwCurrentState := SERVICE_START_PENDING;
         dwControlsAccepted := SERVICE_ACCEPT_STOP or
                               SERVICE_ACCEPT_PAUSE_CONTINUE;
         dwWaitHint := 1000;
      end; // of with m_status do
         [...]
end;
Ich kann mir das leider gar nicht erklären. Wie kann ich aus der übergebenen Methode jetzt ohne eine Speicherverletzung zu bekommen auf die Eigenschaften der Klasse zugreifen?

Phoenix 24. Sep 2003 06:46

Re: Unerlaubte Member-Variablen im Service?
 
*nochmalnachobenzupf* :wink:

Motzi 24. Sep 2003 07:37

Re: Unerlaubte Member-Variablen im Service?
 
Eine Objekt-Methode führt noch einen versteckten Parameter mehr mit - die Self-Referenz, aber von der weiß Windows natürlich nichts. Schau dir dazu mal die beiden Funktionen MakeObjectInstance und FreeObjectInstance an.

Phoenix 24. Sep 2003 13:48

Re: Unerlaubte Member-Variablen im Service?
 
Hi,

ich will a) kein Subclassing machen. IMHO müsste es da auch ne andere Methode geben, das hinzubekommen.

b) möchte ich möglichst vermeiden die Unit classes zu verwenden. Assarbad und Luckie werden mich töten, wenn mein Service dann wegen dieser blöden Sache hier wieder von 20k auf über 100k anwächst.

Also gibt es da noch ne andere Methode? Ich meine eine Klasse MUSS doch auf die eigenen Methoden und Bariablen zugreifen können, oder?

Motzi 24. Sep 2003 13:55

Re: Unerlaubte Member-Variablen im Service?
 
Das hat nicht unbedingt was mit SubClassing zu tun..

Das Problem ist eben, dass eine Methode einen versteckten Parameter mehr mit sich führt, von dem Windows allerdings keine Ahnung hat!

Aber ich werd mal weitersuchen...

Phoenix 24. Sep 2003 14:10

Re: Unerlaubte Member-Variablen im Service?
 
Ich hab grad ein wenig probiert: MakeObjectInstance kann nur mit eienr TWndMethod als Paramater etwas anfangen.

Die Service - Methode braucht jedoch andere Parameter als eine TWndMethod. Der Aufruf ist so also gar nicht kompatibel.

Ich brauche also definitiv eine andere Lösung.

sakura 24. Sep 2003 14:14

Re: Unerlaubte Member-Variablen im Service?
 
Das ist aus verschiedenen Gründen nicht möglich. Einerseits hast Du getrennte Speicherbereiche, andererseits übergibst Du die Adresse der Prozedur im Speicher, allerdings nicht die Adresse der Daten Deines Objektes. Du kannst 1000 Objekte vom Typ PhService haben, aber es wird nur eine Kopie jeder Methode dieser Klasse geben. Das heisst, wenn Du die Adresse der Methode bergibst, so steht diese völlig "leer im Raume" ohne jegliches Wissen über die Objektinstanz.

...:cat:...

Motzi 24. Sep 2003 14:20

Re: Unerlaubte Member-Variablen im Service?
 
Vielleicht hilft dir das weiter:
http://www.swissdelphicenter.ch/de/showcode.php?id=1671

Phoenix 24. Sep 2003 14:44

Re: Unerlaubte Member-Variablen im Service?
 
Äh, nicht ganz. Ist aber so wie es aussieht genau das, was ich brauche.

Ich verstehe nur den Code nicht, der da unten steht. Zuerst wird ein TMyMethod als procedure of object deklariert, später aber nie wieder verwendet.

Dann muss man der MakeProcInstance ein TMethod übergeben. Wie bekomme ich aus der serviceproc - Methode denn nun ein TMethod, um mir den Pointer erstellen zu lassen?

Phoenix 24. Sep 2003 17:15

Re: Unerlaubte Member-Variablen im Service?
 
Oki. Jetzt soweit:

Ich habe verstanden, das ich diese serviceproc via MakeProcInstance (wahrscheinlich am besten beim Instanzieren des Objektes)in einen Pointer auf einen Methodenzeiger verwandeln muss. Diesen übergebe ich dann.

Die Methode bekommt beim Aufruf durch de API-Funktion den self-parameter mit (wird ja in dem Pointer mit dem Objekt verbudnen) und kann somit auf die richtigen Variablen in der Klasse zugreifen. Hinterher muss ich den Speicher des neuen Methodenzeigers (also im Destruktor der Klasse) wieder freigeben.

Womit ich nach dem Codebeispiel im SDC noch Probleme habe ich der richtige Aufruf dieser Funktion. Diese erwartet als Parameter ein TMethod. Wie bekomme ich jetzt meine ServiceProc richtig an MakeProcInstance übergeben?

Hier der Code:
Delphi-Quellcode:
//Man legt einen ausführbaren Speicherbereich an, und schreibt in
// diesen 4 Maschinencodeanweisungen: 2 davon enthalten die beiden
// Pointer (als Konstanten, die in ein Register geschrieben werden,
// 1 den Aufruf der Methode, und 1 die Return-Anweisung. Den Zeiger
// auf den Speicherbereich kann man nun als normalen Funktionspointer
// verwenden, der die Methode für eine ganz bestimmte Instanz aufruft.

function MakeProcInstance(M: TMethod): Pointer;
begin
  // allocate memory
  GetMem(Result, 15);
  asm
    // MOV ECX,
    MOV BYTE PTR [EAX], $B9 
    MOV ECX, M.Data
    MOV DWORD PTR [EAX+$1], ECX
    // POP EDX
    MOV BYTE PTR [EAX+$5], $5A
    // PUSH ECX
    MOV BYTE PTR [EAX+$6], $51 
    // PUSH EDX
    MOV BYTE PTR [EAX+$7], $52 
    // MOV ECX,
    MOV BYTE PTR [EAX+$8], $B9 
    MOV ECX, M.Code
    MOV DWORD PTR [EAX+$9], ECX
    // JMP ECX
    MOV BYTE PTR [EAX+$D], $FF
    MOV BYTE PTR [EAX+$E], $E1 
  end;
end;


procedure FreeProcInstance(ProcInstance: Pointer);
begin
  // free memory
  FreeMem(ProcInstance, 15);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:41 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