Announcement

Collapse
No announcement yet.

DLL: Zeiger auf Tabelle als Übergabeparameter

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

  • DLL: Zeiger auf Tabelle als Übergabeparameter

    Moin, moin!

    Um die Größe meiner Applikation (EXE) in vernünftigen Rahmen zu halten möchte ich die grundliegende Daten-Maintenence (Datensätze anlegen, modifizieren und löschen) einer Tabelle in eine DLL umlagern.

    EXE beinhaltet außer anderen Elementen auch einen DataModul der seinerseits einige Tabellen und Queries beinhaltet. Unter anderem auch die Tabelle, die ich in DLL bearbeiten möchte.

    DLL beinhaltet folgende VCL-Elemente: TABSTable, TDataSource, TDBGrid und TDBNavigator. Alle sind miteinander verknüpft.

    Ich wollte die bearbeitende Funktion (DLL) allgemein halten. Damit wollte ich erreichen, dass ich unterschiedliche Tabellen bearbeiten kann. Also dachte ich mir, dass es reichen würde, dass die Funktion den Zeiger auf die aktuell zu berbeitende Tabelle bekommt. Während der Debug-Session habe ich manche Eigenschaften der Tabelle überprüft und festgestellt, dass sie OK sind.

    Formel passte alles (denke ich). Bisherige Funktionalität der Anwendung ist nicht betroffen worden, Applikation läuft wie gewohnt ohne Probleme. Die neue (und z.Zt. die einzige) DLL wird geladen und Funktion aufgerufen. Problem ist, dass das DBGrid in der DLL keine Daten zeigt. Er sieht aus als ob er mit keiner Tabelle verbunden wäre. Das gleiche betrifft den DBNavigator. Er scheint keine Verbindung zur Tabelle zu haben. Genau so sehen ein DBGrid und ein DBNavigator aus, wenn man sie zum ersten mal auf der Form platziert und noch zur keinen DataSource verbunden hat.

    Und so habe ich die DLL und ihr Aufruf implementiert:

    DLL:
    Deklaration der Funktion (H):
    Code:
    extern "C" __declspec(dllexport) int __stdcall InvokeTabAccess(TABSTable*);

    Definition der Funktion (CPP):
    Code:
    int __stdcall InvokeTabAccess(TABSTable *CurrTable)
    {
            TForm2 *TabAccessForm = new TForm2(NULL);
    
            TabAccessForm->ABSTable1 = CurrTable;
            TabAccessForm->ABSTable1->Active = true;
    
            TabAccessForm->StatusBar1->SimpleText = TabAccessForm->ABSTable1->TableName;
    
            TabAccessForm->ShowModal();
    
            delete TabAccessForm;
    
            return 0;
    }

    EXE:
    Aufruf der Funktion aus der Applikation:
    Code:
    void __fastcall TfrmZE2::Button1Click(TObject *Sender)
    {
            typedef int (*dllfnct)(TABSTable*);
    
            HINSTANCE  gLibMyDLL = NULL;
            dllfnct dllproc;
    
            gLibMyDLL = LoadLibrary("TabAccess");
    
            if (gLibMyDLL)
            {
                    dllproc = (dllfnct) GetProcAddress(gLibMyDLL, "InvokeTabAccess");
    
                    if (dllproc)
                    {
                            dllproc(dmEintrag->ABSTable1);
                    }
            }
    }
    Who can help?

    Viele Grüße
    Markus

  • #2
    Die Verbindungsparameter sind in der DLL in der Form fest verdrahtet? Du nutzt die gleiche Verbindungsdaten wie in der EXE??
    Christian

    Comment


    • #3
      Moin Christian!

      Originally posted by Christian Marquardt View Post
      Die Verbindungsparameter sind in der DLL in der Form fest verdrahtet?
      Wie schon mal erwähnt: auf der DLL-Form habe ich nur eine Tabelle, DataSource, DBGrid und DBNavigator. Es sind keine von ihren Eigenschaften gesetzt ausser das sie alle miteinander verknüpft sind. In der DLL habe ich keine Komponenten zur Datenbankverbindung wie z.B. Database, Session oder ähnliches.

      Originally posted by Christian Marquardt View Post
      Du nutzt die gleiche Verbindungsdaten wie in der EXE??
      Auf der EXE–Form habe ich einen ABSDatabase-Komponent der für die Verbindung zur DB sorgt. Ich habe gehofft, dass die DB-Verbindung in der EXE aufgebaut wird und wenn ich den Zeiger auf die Tabelle an die DLL übergebe, dann habe ich Zugriff auf die Tabelle auch in der DLL.

      Wie gesagt, die Parameteruebergabe selbst funktioniert. Ich habe das geprüft indem ich einen break point direkt vor "ShowModal" in der DLL gesetzt habe. Dann konnte ich mir ein paar Eigenschaften der Tabelle angucken. Die Werte stimmen mit denen in Exe überein. Ausserdem übergebe ich den Tabellennamen an die Statusbar -> der Name stimmt mit dem Namen der Tabelle in EXE überein. Also, meine ich, der Zeiger zeigt auf richtige Tabelle.

      Viele Grüße
      Markus

      Comment


      • #4
        dann wird wohl die Verbindung zur DB fehlen.

        Du hast eine neuen Form mit neuen Komponenten. Da musst du m.E. auch die Verbindung zur DB herstellen.

        Es wird nicht an der Übergabe des Zeigers liegen.
        Christian

        Comment


        • #5
          Kurze Frage: Verwendest Du Laufzeitpackages? Falls nein hast du höchstwahrscheinlich das "Standard-Problem" das du 2 unabhänige Klassenbibliotheken hast (TObject von DLL <> TObject von Exe) und damit jede As/Is-Typüberprüfung (oder was das bei C++ ist) u.U. fehlschlägt.

          Comment


          • #6
            Kurze Frage: Verwendest Du Laufzeitpackages? Falls nein hast du höchstwahrscheinlich das "Standard-Problem" das du 2 unabhänige Klassenbibliotheken hast (TObject von DLL <> TObject von Exe) und damit jede As/Is-Typüberprüfung (oder was das bei C++ ist) u.U. fehlschlägt.
            Kannst du das mal erläutern??

            Eine Typprüfung gibt es in C++ grundsätzlich nicht (Ausnahme RTTI).

            Was wäre die Lösung oder was hat das mit dem Problem zu tun?
            Christian

            Comment


            • #7
              Originally posted by Christian Marquardt View Post
              Kannst du das mal erläutern??

              Eine Typprüfung gibt es in C++ grundsätzlich nicht (Ausnahme RTTI).
              Genau diese mein ich ja. Da ja (meines Wissens) der C++-Builder die Delphi-Implementierung der VCL verwendet und hier vielfach mit is/as auf richtige Typen abgeprüft wird gibt es probleme wenn Exe und DLL nicht mit Laufzeitpackages kompiliert wurden.

              Originally posted by Christian Marquardt View Post
              Was wäre die Lösung oder was hat das mit dem Problem zu tun?
              Lösung: Laufzeitpackages verwende.
              Was hat das mit dem Problem zu tun: Eigentlich sind sehr viele Probleme mit Exe/DLL und "lebenden" Objekten genau daran begründet das keine Laufzeitpackages verwendet werden.

              Comment


              • #8
                Moin, moin!

                Also die Lösung ist gefunden:

                Variante A. (mit „Kopie“ der Tabelle arbeiten)
                Die DLL-Form beinhaltet Tabelle, DataSource, DBGrid und DBNavigator. Alle die Objekten werden zur Zeit des DLL-Aufrufes erstellt. Dann hat man, wie das schon Christian erwähnte, zwei Table-Objekte. Einen in EXE und zweiten in DLL. Das sind zwei von einander unabhängige Table-Objekte, die mit einander nichts zu tun haben und deswegen getrennt von einander betrachtet werden müssen. Um Daten in der DLL zu sehen muss man die DLL-Tabelle ganz normal konfigurieren und aktivieren. Die Eigenschaften der DLL-Tabelle kann man mit Hilfe des übergebenen Zeigers setzen. Sprich: von der originalen EXE-Tabelle übernehmen:

                Code:
                int __stdcall InvokeTabAccess(TABSTable *CurrTable)
                {
                        TForm2 *TabAccessForm = new TForm2(Application);
                
                        TabAccessForm->ABSTable1->DatabaseName = CurrTable->DatabaseName;
                        TabAccessForm->ABSTable1->TableName    = CurrTable->TableName;
                        TabAccessForm->ABSTable1->Active       = true;
                
                        TabAccessForm->StatusBar1->SimpleText  = "Tabellenname: " + 
                                                                 TabAccessForm->ABSTable1->TableName;
                
                        TabAccessForm->ShowModal();
                
                        delete TabAccessForm;
                
                        return 0;
                }
                Variante B. (mit der originalen Tabelle arbeiten)
                Die DLL-Form beinhaltet nur DataSource, DBGrid und DBNavigator -> keine Tabelle. In diesem Fall hat man nur ein Table-Objekt und zwar den in der EXE. Um Daten in der DLL zu sehen und bearbeiten zu können braucht man lediglich die Eigenschaft „DataSet“der DLL-DataSource mit Hilfe des übergebenen Zeigers einzustellen. Sprich: „DataSet“ auf die originale EXE-Tabelle setzen:

                Code:
                int __stdcall InvokeTabAccess(TABSTable *CurrTable)
                {
                        TForm2 *TabAccessForm = new TForm2(Application);
                
                        TabAccessForm->DataSource1->DataSet    = CurrTable;
                
                        TabAccessForm->StatusBar1->SimpleText  = "Tabellenname: " + 
                                                                 TabAccessForm->ABSTable1->TableName;
                
                        TabAccessForm->ShowModal();
                
                        delete TabAccessForm;
                
                        return 0;
                }
                Ich danke Euch für eure Unterstuzung.

                Viele Grüße
                Markus

                Comment

                Working...
                X