Announcement

Collapse
No announcement yet.

Größe von MMF ändern

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Größe von MMF ändern

    Hi.<p>
    Ich hab' mich schlau gemacht und erfahren, dass man die Größe eines MMF nicht ändern kann. Empfohlen wird dabei meist ein zweites MMF zu erstellen und das alte in das neue (von der Größe angepasste) zu kopieren.<p>
    Ich benutze MMFs zur Interprozesskommunikation und möchte darin ein dynamisches Array speichern. Nun geht das natürlich nicht, weil die Größe des Arrays erst feststeht, wenn das MMF bereits angelegt wurde.<p>
    Frage: Gibt es irgendwelche Kniffs, Möglichkeiten, Tricks oder Tipps wie ich es am besten anstellen kann, mein MMF in der Größe anzupassen? Immerhin wäre es ja möglich, dass zwischenzeitlich die Instanz der DLL im anderen Prozessraum auf das MMF zugreifen möchte, während ich dieses gerade in ein neues kopiere. Oder wie sieht es mit dem Namen des MMF aus? Ich kann kein MMF mit einem gleichen Namen erstellen, aber muss doch irgendwie sichergehen, dass ich immer das richtige MMF anspreche.<p>
    Hm, Fragen über Fragen...<p>
    Ich bin gespannt über Euere Gedankenanstöße!<p>
    Viele Grüße,<br>
    Markus

  • #2
    Grundsätzlich musst du sowieso berücksichtigen das ein Prozess alleine den Exklusivzugriff auf ein MMF haben kann. Dieser Fall tritt ein wenn das MMF kopiert oder angelegt oder hineingeschrieben wird. MMF's werden vom OS eben NICHT zwischen den Prozessen synchronisiert. D.h. normalerweise wird ein globales MMF immer mit einem globalen Event + Semaphore geschützt.<br>
    Ich würde ein globales MMF mit fester Größe benutzen. In diesem MMF stehen die Namen und die Handles von Child-MMF's, deren Processe und Thread's. Wird ein neues MMF benötigt so wird es mit der neuen Größe angelegt, dann die Daten des alten MMF's hineinkopiert, die zusätzlichen Daten rangehängt. Danach wird das alte MMF Handle/Name im globalen MMF mit dem neuen ersetzt.<br>
    Für diese Operationen sollte aber der Ownerprozess des globalen MMF's zuständig sein.<br>
    D.h. über ein festes Array in einem MMF werden die eigentlichen Daten-MMF's verwaltet und global zur Verfügung gestellt.<br>

    Gruß Hage

    Comment


    • #3
      Hi Hagen!<p>
      Hört sich gut an.<br>
      Ich habe dann 2 MMFs. Das "alte" und ein neues, in dem das dyn. Array abgelegt wird. Im alten speichere ich eine Referenz auf das neue, das bei Bedarf angelegt wird.<p>
      Habe ich das grundsätzlich richtig verstanden? ;-)<p>
      Gruß,<br>
      Marku

      Comment


      • #4
        nicht ganz, ich habe mich da ein bißchen diffus ausgedrückt.<br>
        Ein MMF dient zur Verwaltung der gerade gültigen Daten-MMF's. Dieses Index-MMF hat immer feste Größe und verwaltet die Handles/Namen der gerade gültigen Daten-MMFs. Will ein Process auf ein Daten MMF zugreifen dann tut es dies indem über das Index-MMF über den Index in dieses Array direkt den Namen des Daten-MMF's in Erfahrung bringt. Somit kann der Name der Daten-MMF's beliebig sein.<br>
        z.b.

        <pre>

        type
        TMMFIndex = array[0..15] of packed record
        Handle: THandle; // Handle des MMF's
        Size: DWord; // Größe des MMF's
        Lock: TRTLCriticalSection; // globale RTL zum Sperren des MMF's
        ProcessID: DWord; // Owner Process des MMF's, rein informativ
        ThreadID: DWord; // Owner Thread des MMF's
        Name: array[0..127] of Char; // Name des MMF's
        end;

        </pre>

        Obiges TMMFIndex ist die Struktur die per MMF mit fester Größe zur Verfügung gestellt wird. Nun kannste in die DLL funktionen schreiben die über dieses Array[] per festen Index auf die einzelenen Daten-MMF's zugreifen.<br> Soll nun eines dieser Daten-MMF's vergrößert werden so gibts dafür eine Funktion in dieser DLL.<br>

        Gruß Hage

        Comment


        • #5
          Hi Hagen!<p>
          Danke für die Antwort. Nun verstehe ich die Sache schon mehr, auch wenn ich so ein Gewurschtel eigentlich vermeiden wollte ;-)<br>
          Ich muss momentan mal wieder etwas kürzer treten beim Programmieren, aber ich halte Dich auf dem Laufenden wie es funktioniert. Eine (blöde) Frage habe ich aber dennoch: Wieso verwenden wir diesmal nicht eine Semaphore (siehe meine Callback-Frage), sondern eine TRTLCriticalSection?<p>
          Danke, Du weißt wie sehr ich Deine Hilfe schätze!<p>
          Viele Grüße,<br>
          Marku

          Comment


          • #6
            CS könnte man wie ein Sempahore betrachten, es ist sogar so das das OS intern CS per Semaphoren umsetzt. Der wesentlichste Unterschied ist der das Semaphoren die Möglichkeit bieten die Anzahl der Threads die diese "Schranke" passieren dürfen auf mehr als 1 Thread zu beschränken. Eine CS ist also eine Semaphore die nur EINEN Thread durchlässt und die anderen blockiert. ABER, genau diese Blockierung ist ein wesentlicher Unterschied zwischen Semaphoren und CS. Eine CS implementiert einen Mechanismus der den anderen, blockierten Threads, mitteilt das der blockierende Thread (der der die CS passiert hat und sie sperrt) nun fertig ist. Danach lässt die nun entsperrte CS den nächten wartenden Thread durch, und zwar NUR diesen, alle anderen wartenden Thread bleiben weiterhin blockiert und warten anständig. Die Entscheidung welcher Thread der nächste ist wird an hand dessen Priorität und Aufrufreihenfolge festgemacht. So, all diese Features bestitzen Semahore NICHT. Man muß also die alles selber coden. Im Normalfalle wird bei Semaphoren, bei nicht Erfolg, einfach die Funktion mit einem Fehler verlassen. D.h. der Thread WARTET NICHT.<br>

            Gruß Hage

            Comment


            • #7
              Hi Hagen,<p>
              kannst Du mir bitte, bitte nochmals ein paar Infos geben? Ich komm' nicht weiter <p>
              1. Muss ich nun für alle 3 MMFs (Index, "HookRec", "dynArrayRec") eine map und eine MMF anlegen? Boah, das bläht die DLL mächtig auf...<br>
              2. Wie greife ich über das IndexMMF auf meine HookRec (Index 0) zu?
              -> z.B. MMFIndex^[0].Handle.oldProc ???<p>
              Hm, sorry, dass ich mich so "dappig" anstelle...<p>
              Viele Grüße,<br>
              Marku

              Comment


              • #8
                Was meinst du mit HookRec ??<br>

                Du benötigst ein MMF das die Liste aller Daten MMF's speichert. D.h. im Grunde kannst du 2,3,4 sogar 1000 MMF's in diesem Index-MMF verwalten.<br>

                Da MMF's nicht in der Größe verändert werden können muß das MMF in ein neues größeres kopiert werden. Dazu wird über das "Index" MMF das Daten MMF gesperrt. Dann ein neues, größeres MMF alloziert, der Inhalt hineinkopiert, die Einträge im Index MMF die auf das Source MMF zeigen durch das neue ersetzt, und das alte Source MMF gelöscht.<br>

                Das neue MMF hat dann auch einen anderen Namen. Um nun denoch das richtige MMF auswählen zu können, wird es über den Absoluten Index in das Index MMF Array angesprochen. Also nicht per globalen Namen, sondern per fester ID oder Index.<br>

                Gruß Hagen

                PS: ein anderer Name für das Index-MMF wäre zb. "Handle-Tabelle" auf MMF's. Ich würde aber pro MMF einen Record speichern der noch zusätzliche Info's zum MMF speichert. Sprich Handle, Name, Size, Owner, RTL-CS, Events usw.<br>
                &#10

                Comment


                • #9
                  Hi Hagen!<p>
                  <i>>> Was meinst du mit HookRec ??</i><p>
                  Ja, das kommt mal wieder davon, wenn man noch schnell einen Post schreiben will... Sorry!<br>
                  HookRec ist einfach das record meiner MMF, in dem ich das Hook Handle, die alte Window Proc usw. speichere. Das andere MMF (record) soll mein dynamisches Array enthalten (und beide sollen wiederum im Index enthalten sein, klar). Saudumm von mir geschrieben, nochmals Entschuldigung dafür.<p>
                  Meine Frage ging in diese Richtung:<p>
                  <pre><code>
                  type
                  THookRec = packed record
                  Hook: hHook;
                  //...
                  oldProc: Integer;
                  end;
                  </code>
                  <code>
                  //...
                  </code>
                  <code>
                  var
                  HookRec: ^THookRec;
                  </code>
                  <code>
                  // ...
                  </code></pre>
                  Wie komme ich nun auf die Variable Hook (z.B.) unter Verwendung des angelegten Index?<br>
                  Wie schütze ich den Zugriff auf das Index MMF? Auch mit CriticalSections oder lieber mit Semaphoren?
                  Gruß,<br>
                  Markus<p>
                  PS: Ich glaube, meine Auszeit in diesem Projekt war einfach zu lange, sorry für die laufenden dummen Fragen... :

                  Comment


                  • #10
                    So nun mal Klartext: Du willst in der DLL bestimmte Fenster subclassen ?! richtig ?<br>

                    Dann geht das ohne MMF's, ohne solche Tricks wie Semaphores, usw.<br>

                    Je nachdem ob du nur 1 oder 2 Fenster "hooken" oder sehr viele hooken möchtest gibt es zwei Wege.
                    <li>globaler Fensterhook über SetWindowHookEx()<br>
                    <li>gezieltes SubClassing über SetWindowLong(gwl_WndProc, ..)<br>

                    Normalerweise wird in der zweiten Methode alle notwendigen Daten, wie alte Fensterprocedure usw. IM Fenstser selber gespeichert. Jedes Fensterhandle hat dyn. erweiterbare Speicherbereiche. Diese werden mit SetProp() und Konsorten gelesen, geschrieben, gelöscht. Solche Prop's arbeiten Prozessübergreifend.<br>

                    Gruß Hage

                    Comment


                    • #11
                      <i>>> Du willst in der DLL bestimmte Fenster subclassen ?! richtig ?</i><p>
                      Yep, richtig.<p>
                      <i>>> Dann geht das ohne MMF's, ohne solche Tricks wie Semaphores, usw.</i><p>
                      Ja, auch richtig. Es gibt natürlich mehrere Möglichkeiten... <br>
                      Naja, jedenfalls habe ich den Spleen bei Hooks mit MMFs zu arbeiten von Madshi. Ich dachte der Großmeister des Hookings gab mir da einen Profitip :/<p><p>
                      Also, wieder zum "Klartext": Ich misbrauche (bis jetzt noch) SetWindowsHookEx() um in den target process zu kommen, danach subclasse ich das Fenster mit SetWindowsLong(). Mein Ziel ist es meiner injezierten DLL Informationen zukommen zu lassen (per Funktion in der DLL). Da die Funktion in der DLL, die vom Anwenderprogramm aufgerufen wird, jedoch in einem anderen (meinem) Speicherkontext läuft muss ich etwas tricksen. Also, aber diese Informationen (window handles, window classes und deren Captions) sollen in ihrer Anzahl nicht beschränkt sein, deshalb dynamisch und hier fängt mein Problem mit dem MMF an. Wichtig ist, dass ich diese Fenster <i>nicht</i> subclassen möchte. Ich benötige sie nur um in der gesubclassten window proc (1 Fenster!) messages abzufangen (und eben Messages mit diesen Infos als Parametern werden abgefangen und verändert)...<p>
                      Ich werde mir die Sache mit SetProp() etwas näher ansehen.<p>
                      Viele Grüße,<br>
                      Marku

                      Comment


                      • #12
                        Dann mißbrauche doch das subclassed Fenster als Message-Handler zwischen den Prozessen. Dies ist einfacher als über MMF's zu gehen. Normalerweise sind MMF's eher statisch, d.h. jeder interessierte Prozess ist selber dafür verantwortlich Änderungen am MMF zu erkennen. Normalerweise spaltet dafür jeder Prozess einen Thread ab der auf Änderungen eines Events wartet. Diese Event wird gepulst wenn irgendeine eine Änderung am MMF gemacht hat. Im Grunde übernimmt die teilweise das OS, da man auch das Handle des MMF's statt eines Events so nutzen kann. Siehe WaitForSingleObject().<br>

                        ABER: du willst mehr dynamic, heist gezielt Änderungen vermelden, bzw. gezielt Nachrichten absetzen.<br>

                        Überlege dir mal ob es vielleicht günstiger ist in der DLL einen kleinen TCP/IP Server zu integrieren. Dann könnte die Steuerungssoftware auch übers Netz/WEB mit der DLL kommunizieren.<br>
                        Der Aufwand ist so oder so rel. hoch, besonders um es bugfree und flüssig zum laufen zu bekommen. Mit dem TCP/IP hättest du zumindestens das Synchronisationsproblem beseitigt. RPC=remote procedure calls arbeiten ähnlich.<br>

                        Gruß Hage

                        Comment


                        • #13
                          <i>>> Dann mißbrauche doch das subclassed Fenster als Message-Handler zwischen den Prozessen.</i><p>
                          Oh nein, ich De..! Das ist wirklich ein Weg, der sogar mir hätte einfallen müssen <br>
                          Danke, das wird funktionieren.<p>
                          Bzgl. RPC, TCP/IP: Ich habe mich darüber schon oft schlau gemacht und bemerkt, dass viele Profis diese Methode verwenden (wenn's wirklich zur Sache geht ;-). Aber davon halte ich mich bis jetzt noch fern, ich will ja nicht gleich über's Ziel hinausschießen.<p>
                          Nochmals Danke für Deine Hilfe und Deine guten Nerven <p>
                          Gruß,<br>
                          Markus<p>
                          PS: Das mit dem MMF werde ich trotzdem (bei gegebener Zeit) versuchen, aus reinen Lehrzwecken ;

                          Comment


                          • #14
                            Oder übers COM, da MS COM ja auch prozessüberreifend arbeiten kann. Allerdings ist hier Andreas Kosch fitter als ich.
                            Ich weiß nicht ob bei Injekt-DLL's COM noch arbeitet.

                            Gruß Hage

                            Comment

                            Working...
                            X