capi2032.dll Einbindungsproblem....



  • Hi all...

    ich will mich mit der CAPI beschäftigen. Dazu hab ich ein ganz kleines Prog
    geschrieben um erstmal die DLL-Einbindung hinzubekommen.
    Ich denke die Einbindung funktioniert auch, aber wenn ich auf eine Funktion
    aus dieser zugreifen möchte tritt immer ne Exeption auf, d.h. irgendwas
    stimmt wohl noch nicht so richtig. Vielleicht könnt ihr mir da weiterhelfen
    und mal schaun was ich da evtl. noch falsch mache...

    Hier mein Quellcode, der nicht anders macht, als zu überprüfen ob die CAPI
    überhaupt installiert ist.

    /* .h file */
    
    class TfrmMain : public TForm
    {
    __published:    // Von der IDE verwaltete Komponenten
            TButton *Button1;
            void __fastcall Button1Click(TObject *Sender);
            void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    private:    // Anwender-Deklarationen
            typedef unsigned int (_cdecl *FN_CAPI_INSTALLED)(void);
    
            FN_CAPI_INSTALLED    *pCapi_Installed;
    
    public:     // Anwender-Deklarationen
            __fastcall TfrmMain(TComponent* Owner);
    };
    
    /* .cpp file */
    
    TfrmMain *frmMain;
    HINSTANCE LibInstance;
    
    //---------------------------------------------------------------------------
    __fastcall TfrmMain::TfrmMain(TComponent* Owner)
            : TForm(Owner)
    {
      LibInstance = ::LoadLibrary("Capi2032.dll");
      pCapi_Installed        = (FN_CAPI_INSTALLED*)::GetProcAddress((HMODULE)LibInstance, "CAPI_INSTALLED");
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::Button1Click(TObject *Sender)
    {
       if(LibInstance != NULL)
       {
          if (pCapi_Installed)   
          {
            int x = (*pCapi_Installed)();  /* hier tritt Exeption auf */
          }
        }
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
    {
      FreeLibrary(LibInstance);
    }
    //---------------------------------------------------------------------------
    

    Seht ihr was hier vielleicht net stimmt? Warum die Exeption auftritt?

    Danke für jeden Tip! Vielleicht hat sich ja schon mal jemand damit beschäftigt.
    MfG
    Hevel



  • ich mache um Zeiger auf Funktionen immer einen großen Bogen und nutze die nur bei selbstdefinierten Ereignisbehandlungsroutinen in selberentwickelten Komponenten.

    Deshalb der ganz vorsichtige Versuch:

    In Deiner private-Deklaration definierst Du FN_CAPI_INSTALLED als Zeiger auf eine Funktion. Dann deklarierst Du einen Zeiger auf einen Zeiger einer Funktion, wenn ich mir die doppelten Sterne so ansehe. Wenn Dein Funktionsaufruf in der Methode Button1Click syntaktisch in Ordnung ist (müßte ich auch in der Hilfe herumsuchen...), dann könnte ich verstehen, daß es kracht, weil er dann einen Code an der Stelle ausführen will, an der der Zeiger auf die Funktion steht.

    Vielleicht is das auch Käse, aber ein Versuch wäre es ja wert? 🙄



  • Danke JFK!

    Das hab ich mal geändert... und jetzt funktioniert das auch soweit. Also
    keine Exeptions.

    Ich hab hier nochmal meinen geänderten Code. Der überprüft, ob
    CAPI installiert ist und wenn ja, soll er mir den Herstellernamen
    ausgeben. Es treten hierbei auch keine Fehlermeldungen auf, jedoch
    klappt das nicht, dass der Name in den "Buffer" geschrieben wird.
    Und nun weiß ich nicht warum.
    Vielleicht kann mal jemand reinschaun.. ich werd da echt nicht schlau.
    Die funktionen hab ich der CAPI-Doku entnommen.

    /* .h file */
    class TfrmMain : public TForm
    {
    __published:    // Von der IDE verwaltete Komponenten
            TButton *Button1;
            void __fastcall Button1Click(TObject *Sender);
            void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    private:    // Anwender-Deklarationen
            typedef unsigned char (FN_CAPI_INSTALLED)(void);
            typedef unsigned char* (FN_CAPI_GET_MANUFACTURER)(int Ctrl, unsigned char *Buf);
    
            FN_CAPI_INSTALLED    *pCapi_Installed;
            FN_CAPI_GET_MANUFACTURER *pCapiGetManufacturer;
    
    public:     // Anwender-Deklarationen
            __fastcall TfrmMain(TComponent* Owner);
    };
    
    /* .cpp file */
    
    TfrmMain *frmMain;
    HINSTANCE LibInstance;
    
    //---------------------------------------------------------------------------
    __fastcall TfrmMain::TfrmMain(TComponent* Owner)
            : TForm(Owner)
    {
      LibInstance = ::LoadLibrary("Capi2032.dll");
      pCapi_Installed        = (FN_CAPI_INSTALLED*)::GetProcAddress((HMODULE)LibInstance, "CAPI_INSTALLED");
      pCapiGetManufacturer   = (FN_CAPI_GET_MANUFACTURER*)::GetProcAddress((HMODULE)LibInstance, "CAPI_GET_MANUFACTURER");
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::Button1Click(TObject *Sender)
    {
       if (pCapi_Installed != NULL && pCapiGetManufacturer != NULL)
       {
         int x= 1;
         x = (*pCapi_Installed)();    //  returns 0 if CAPI is installed
    
         if(!x)
         {
           unsigned char Buffer[65];           // 64 Byte Buffer
           unsigned char* pBuf = NULL;
    
           /* schreibt Herstellername in Buffer
              Klappt irgendwie nicht ! ?? */
           /* return: Pointer to the Buffer */
              pBuf = (*pCapiGetManufacturer)(0,Buffer);
    
           if (pBuf != NULL)
             MessageBox(0, Buffer, "Test", 0);   // Ausgabge
         }
       }
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
    {
      FreeLibrary(LibInstance);
    }
    //---------------------------------------------------------------------------
    

    Jetzt weiß ich echt net mehr weiter... son Mist.
    Ihr?

    MfG
    Hevel



  • Schreib doch in den ersten Parameter mal was anderes rein, z.B. 5 oder so.



  • Hallo erst mal,

    habe mich auch eine Zeit lang mit der Capi beschäftigt. Habe mal ein Prog. geschrieben das auf eingehende Anrufe wartet.

    Der Fehler liegt hier:

    typedef unsigned char* (FN_CAPI_GET_MANUFACTURER)(int Ctrl, unsigned char *Buf);
    

    Bei CapiGetManufacturer gibt es keinen Übergabeparameter "Ctrl", wo immer du es her hast es ist Falsch!

    Habe das so realisiert:

    // .h
    
    typedef dWORD (__stdcall *TCapi_Installed)(void);
    typedef dWORD (__stdcall *TCapi_GetManufacturer)(char *SzBuffer);
    
    extern TCapi_Installed       Capi_Installed;
    extern TCapi_GetManufacturer Capi_GetManufacturer;
    
    // .cpp
    
     TCapi_Installed       Capi_Installed;
     TCapi_GetManufacturer Capi_GetManufacturer;
    
    bool __fastcall LoadCapiDLL()
    {
      THandle LibHandle=NULL;
       (void*)LibHandle = LoadLibrary(Capi);
       if(LibHandle == 0){
         Form1->StatusBar1->Panels->Items[1]->Text = "CAPI2032.DLL nicht gefunden";
        // Form1->Memo1->Lines->Add("CAPI2032.DLL nicht gefunden");
         return false;
       }
       Capi_Installed = (TCapi_Installed)GetProcAddress((HINSTANCE)LibHandle, "CAPI_INSTALLED");
       if(Capi_Installed == NULL){
         Form1->StatusBar1->Panels->Items[1]->Text = "32-Bit Capi nicht instaliert !";
     //    Form1->Memo1->Lines->Add("32-Bit Capi nicht instaliert !");
         return false;
       }
       Capi_GetManufacturer = (TCapi_GetManufacturer)GetProcAddress(
                               (HINSTANCE)LibHandle, "CAPI_GET_MANUFACTURER");
    
      return true;
    }
    

    Wobei ich sagen muß, alles was mit Capi zu tun hat habe ich in eine extra Unit und Header-Datei geschrieben und nicht ins Hauptprogramm. Das hat im meinen Sinnne den Vorteil das du die Capi-Sachen ohne Probleme erweitern und in anderen Programmen einbinden kannst.

    In der HauptUnit brauchst du nur noch LoadCapiDLL aufzurufen.

    [ Dieser Beitrag wurde am 26.01.2003 um 00:56 Uhr von e=mc² editiert. ]



  • Das lief bei mir überhaupt nicht. AccessViolations ohne Ende. Folgendes klappt bei mir wunderbar:

    // In der Header-Datei
    typedef DWORD (__stdcall FN_CAPI_INSTALLED)(void);
    typedef void (__stdcall FN_CAPI_GET_MANUFACTURER)(char*);
    
    class TForm1 : public TForm
    {
    __published:    // Komponenten, die von der IDE verwaltet werden
        TButton *Button1;
        void __fastcall Button1Click(TObject *Sender);
    
    private:    // Benutzerdeklarationen
        FN_CAPI_INSTALLED*           pCapi_Installed;
        FN_CAPI_GET_MANUFACTURER*    pCapi_GetManufacturer;
        HINSTANCE                    hDllInst;
    
    protected:
        bool LoadCapiDll();
    
    public:     // Benutzerdeklarationen
        __fastcall TForm1(TComponent* Owner);
    };
    
    // In der cpp-Datei
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
       hDllInst = NULL;
    }
    //---------------------------------------------------------------------------
    
    bool TForm1::LoadCapiDll()
    {
       hDllInst = LoadLibrary("Capi2032.dll");
       if(!hDllInst)
          return false;
    
       pCapi_Installed = (FN_CAPI_INSTALLED*)GetProcAddress(hDllInst, "CAPI_INSTALLED");
       if(!pCapi_Installed)
          return false;
    
       pCapi_GetManufacturer = (FN_CAPI_GET_MANUFACTURER*)GetProcAddress(hDllInst, "CAPI_GET_MANUFACTURER");
       if(!pCapi_GetManufacturer)
          return false;
    
       return true;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
       LoadCapiDll();
    
       if(pCapi_Installed())
          ShowMessage("Not installed");
       else
       {
          char buf[64];
          pCapi_GetManufacturer(buf);
          ShowMessage(buf);
       }
    
       FreeLibrary(hDllInst);
    }
    


  • Hier habe ich eine gute Seite gefunden, die sich mit der CAPI-Programmierung beschäftigt. 🙂



  • Also ich danke euch beiden erstmal! Das ist echt super.

    @e=mc² Das mit den Parametern hab ich aus der Doku... hab mich an der
    für Winn2000 orientiert... aber ich muss wohl die für XP nehmen...
    damm funktionierte es auch. Da hätt ich lange suchen können.

    @WebFritzi.. Danke für die Doku... die ist net schlecht.

    Dank euch hab ich das mal zum laufen bekommen und kann jetzt alle
    Angaben wie Manufacturer abfragen und ausgeben.
    Auch die Registrierung hab ich hinbekommen. Als nächstes muss
    ich mich halt mal an die Messages machen...
    Aber vorher pack ich das alles mal zusammen ich eine Klasse.

    Thx a lot!
    MfG
    Hevel



  • Kein Problem.

    Von der HP die WebFritzi angegeben hat, habe ich auch einige Sachen mir abgeschaut.
    CAPI ist eiin ganz schön harter Brocken, wenn es dann um die Message geht, wünsch ich dir viel Spaß.



  • Ich verstehe auch nicht, wie Leute immer wieder dazu kommen, saukomplizierte Konventionen zu erschaffen. Siehe MS in einigen Fällen. Da habe ich doch lieber mehrere Funktionen, die leichter zu bedienen sind als wenigere, die mehr abdecken sollen und dadurch superschwer zu verstehen sind.



  • Na aus einen ganz einfachen Grund.
    Um die Leute davon abzuhalten mit diesen Sachen zu Programmieren, nach den Motto: "Sollen das mal die Profis machen."

    Genauso wie Treiber programmierung für Windoof, sowas von undurchsichtig, nenene!


Anmelden zum Antworten