Dynamischer Zugriff auf eine dll



  • Hast Du schon mal versucht das Sternchen wegzulassen?

    void __fastcall TProfibus::Init(int SlaveID_int, unsigned int uPort)
    // ...
     if (pDPInit(Test_var, Test_var)==DP_NO_ERROR) // ohne *
    // ...
    }
    

    Wie hast Du eigentlich pDPInit deklariert?

    Gruß,

    Alexander



  • Dann krieg ich bei der if eine Exception....
    da kommt sie:

    if (pDPInit)//hierund zwar eine ganz normale Zugriffsverletzung... :( die Var. ist irgendwie 000000000 aber ich weiss nicht warum... :(
     {
     if (pDPInit(pDll, pIni)==DP_NO_ERROR)
     ShowMessage("Juhui!");
     }
    


  • Weil, wie ich dir andernorts schon gesagt habe bei "pDPInit = (DLLFUNCTION*)::GetProcAddress(hInstance, "DPInit())"); " nur derFunktionsname übergeben werden soll. Anschliessendist es natürilch unerlässlich, den Zeiger anschliessend auf NULL zu prüfen.

    btw. statt dem C-Caste wäre hierder C++-style reinterpret_cast zuv erwenden.

    -junix



  • An der Stelle war doch gar kein * 😕
    Warum fügst Du unten einen * ein, wenn der Fehler ganz woanders auf-
    tritt?

    Gruß,

    Alexander

    P.S.: Wie war doch gleich die Deklaration?



  • junix schrieb:

    Weil, wie ich dir andernorts schon gesagt habe bei "pDPInit = (DLLFUNCTION*)::GetProcAddress(hInstance, "DPInit())"); " nur derFunktionsname übergeben werden soll. Anschliessendist es natürilch unerlässlich, den Zeiger anschliessend auf NULL zu prüfen.

    btw. statt dem C-Caste wäre hierder C++-style reinterpret_cast zuv erwenden.

    -junix

    Was meinst du genau? *nichtganzdrauskomm*

    Alexander Kempf schrieb:

    P.S.: Wie war doch gleich die Deklaration?

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #ifdef _WIN32
        #include <windows.h>
    #endif
    #include <ProfDPAPI.hpp>
    #include "TProfibus.h"
    #include "Tools.h"
    #include "MainForm.h"
    // local variables
    static HANDLE					ConsoleOutput;	// console output
    static CONSOLE_SCREEN_BUFFER_INFO		ConsoleInfo;	// current console info
    static UINT					uNotifyMessage;	// notify message
    
    // prototypes
    static bool InitCommunication(unsigned int uPort);
    static bool StopCommunication(void);
    static bool GetAnswer(void);
    static bool DpeGetAnswer(void);
    static bool ReceiveMessages(void);
    static bool OperationMenu(void);
    static bool DpeOperationMenu(void);
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    __fastcall TProfibus::TProfibus()
    {
    	ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    	if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
    	{
    
    	}
    
    HINSTANCE hInstance;
    hInstance = ::LoadLibrary("prof_dp.dll");
    pDPInit = (DLLFUNCTION*)::GetProcAddress(hInstance, "DPInit()");
    
    }
    //---------------------------------------------------------------------------
    __fastcall TProfibus::~TProfibus(void)
    {
    FreeLibrary(pDPInit);
    }
    //---------------------------------------------------------------------------
    void __fastcall TProfibus::Init(int SlaveID_int, unsigned int uPort)
    {
    char *pIni="COM1,SA1,01,00,60,09,C0,12,33,00,7D,7E,01,01,00,10,08,31,00,C8,00,90,01,00,02,6B,00,0B,00",
         *pDll= "fdlrs";
    int Test_var;	// result configuration
    if (pDPInit)            // testen ob die Var noch gültig ist EXCEPTION HIER
     {
     if (pDPInit(pDll, pIni)==DP_NO_ERROR)
     ShowMessage("Juhui!");
     }
    }
    //---------------------------------------------------------------------------
    static bool InitCommunication(unsigned int uPort)
    {
    return true;
    }
    //---------------------------------------------------------------------------
    


  • "pDPInit = (DLLFUNCTION*)::GetProcAddress(hInstance, "DPInit())"); "
    Die Klammern sind völlig überflüssig, denn die DLL kennt eh nur das Export-symbol sprichdenFunktionsnamen.

    Lies mal die API-Doku zu GetProcAddress.

    wie ist pDPInit deklariert?

    -junix



  • junix schrieb:

    "pDPInit = (DLLFUNCTION*)::GetProcAddress(hInstance, "DPInit())"); "
    Die Klammern sind völlig überflüssig, denn die DLL kennt eh nur das Export-symbol sprichdenFunktionsnamen.

    Zumal auch noch eine schließende Klammer zu viel drin steht.

    junix schrieb:

    wie ist pDPInit deklariert?

    Ja, fehlt immer noch (vielleicht mal den Header zeigen?).

    Gruß,

    Alexander



  • hallo,

    ein kompletter guidline für die erstellung und einbindung von dlls

    http://bcb-tutorial.c-plusplus.net/DLL_Tutorial/artikel1.html

    in cpp

    mfg
    murph



  • [Fullquote gelöscht]

    Danke Murphy, aber das hilft mir bei meinem Problem nicht wirklich weiter... 😞

    Edit:
    Zitate bitte auf das Notwendigste beschränken. Danke!



  • HINSTANCE hInstance;
    hInstance = ::LoadLibrary("prof_dp.dll");
    pDPInit = (DLLFUNCTION*)::GetProcAddress(hInstance, "DPInit()"); //BREAKPOINT
    }
    

    Wenn ich bei pDPInit = (DLLFUNCTION*)::GetProcAddress(hInstance, "DPInit()"); einen Breakpoint setze, hat pDPInit in diesem moment einen Wert, wenn ich dann aber eins weiter steppe heisst es bereits wieder:"NULL" warum das, die Var wird ja nicht verändert... 😕
    Und in der Variable hInstance steht nach hInstance = ::LoadLibrary("prof_dp.dll"); 10000000 drin, was ein sehr komischer Wert für eine Adresse ist. und ähm die dll liegt SICHER im selben Verzeichniss und ist SICHER richtig geschrieben und ich hab' die Datei auch noch ins c:\WINNT\System32 hinein kopiert, nützt auch nichts, selbes Ergebniss... 😞 Wo muss die Datei noch liegen



  • Liest du eigentlich die Antworten? Die Klammern müssen aus dem String raus.



  • Hallo,

    Das wird wohl daran liegen, dass deine Funktion NULL zurück liefert weil ein Fehler aufgetreten ist. Werte doch mal den Fehler mit GetLastError aus.
    Bloss so als Frage. Müsste der Funkionsname nicht so angegeben werden: "_DPInit" ?

    Ciao



  • Ah, okay, doch hab' ich gelesen aber habs nicht so ganz verstanden, okay, jetzt hab' ich die Klammern weg und es gibt immernoch 'ne Exception... 😞



  • __fastcall TProfibus::TProfibus()
    {
    	/*ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    	if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
    	{
    
    	}*/
    HINSTANCE hInstance;
    hInstance = ::LoadLibrary("prof_dp.dll");
    pDPInit = (DLLFUNCTION*)::GetProcAddress(hInstance, "_DPInit");
    long x = GetLastError();
    }
    //---------------------------------------------------------------------------
    __fastcall TProfibus::~TProfibus(void)
    {
    FreeLibrary(pDPInit);                 // allozierter Speicher für dll wieder freigeben
    }
    //---------------------------------------------------------------------------
    void __fastcall TProfibus::Init(int SlaveID_int, unsigned int uPort)
    {                                     // einstellen des COM-Ports und der Busgeschwinigkeit
    char *pIni="COM1,SA1,01,00,60,09,C0,12,33,00,7D,7E,01,01,00,10,08,31,00,C8,00,90,01,00,02,6B,00,0B,00",
         *pDll= "fdlrs";
    int Test_var;	                      // result configuration
    if (pDPInit)                          // testen ob die Var noch gültig ist
     {
     if (pDPInit(pDll, pIni)==DP_NO_ERROR)// Initialisierung des Profiadapters
     ShowMessage("Juhuuuuuuuuuuuuuuuiiiiiiiiiiiiiii!!!!!!!!!!!!!");
     }
    }
    //---------------------------------------------------------------------------
    

    Okay, jetzt hab' ichs so.
    Und in x steht 127, d.h. "The specified procedure could not be found."
    Auf was bezieht sich das genau? 😕



  • Hallo,

    Das heisst nur, dass die angegebene Funktion nicht gefunden wurde. Versuchs doch mal ohne "_".
    Ich hab mir die dll mal kurz besorgt und die Definitionen extrahiert. Das sieht dann so aus:

    LIBRARY PROF_DP.DLL

    EXPORTS
    DPChangeAddress @7 ; DPChangeAddress
    DPCloseSlave @10 ; DPCloseSlave
    DPDoCycleComm @14 ; DPDoCycleComm
    DPDoSingleComm @13 ; DPDoSingleComm
    DPEnableCommThread @15 ; DPEnableCommThread
    DPExit @3 ; DPExit
    DPGetAsyncResult @17 ; DPGetAsyncResult
    DPGetCfg @8 ; DPGetCfg
    DPIdentifySlave @6 ; DPIdentifySlave
    DPInit @2 ; DPInit
    DPOpenSlave @9 ; DPOpenSlave
    DPReadSlaveData @11 ; DPReadSlaveData
    DPSetDispatchMessage @4 ; DPSetDispatchMessage
    DPSetUserMsg @16 ; DPSetUserMsg
    DPSethWnd @5 ; DPSethWnd
    DPWriteSlaveData @12 ; DPWriteSlaveData



  • Okay, ohne "_" hab ich 0 in der Variable x, d.h. "The Operation completed successfully", ist schon mal gut aber hInstance hat immernoch einen Wert von 10000000 und die Exception kommt unten bei der if abfrage immernoch... 😞



  • Das mit hinstance kann schon stimmen.
    Mir scheint, dass vielleicht dein Cast auf DLLFUNCTION* daneben gegangen ist. Vielleicht ist deine Funktion nicht von diesem Typ.



  • roN schrieb:

    die Exception kommt unten bei der if abfrage immernoch... 😞

    Bei welcher der if-Abfragen?
    Und, auch auf die Gefahr hin, daß ich mich (und andere) wiederhole:
    Wie ist die Deklaration von pDPInit? (Oder ist das streng geheim?)

    Gruß,

    Alexander



  • Bei folgender if abfrage:

    if (pDPInit)
    {
    //code
    }
    

    Alexander Kempf schrieb:

    Wie ist die Deklaration von pDPInit? (Oder ist das streng geheim?)

    Nein, natürlich nicht, sorry... das header-file sieht so aus:

    //---------------------------------------------------------------------------
    #ifndef TProfibusH
    #define TProfibusH
    
    //---------------------------------------------------------------------------
    class TProfibus
    {
    public:
           __fastcall TProfibus(void);
           __fastcall ~TProfibus(void);
           void __fastcall Init(int SlaveID_int, unsigned int uPort);
    private:
           typedef int (TDPResult)(char*, char*);
           TDPResult   *pDPInit;
           TDPResult   *pOpenSlave;
    protected:
    };
    //---------------------------------------------------------------------------
    #endif
    

    Ich hab den cast in der Funktion übrigens angepasst auf: pDPInit = (TDPResult*)::GetProcAddress(hInstance, "DPInit");



  • Ich habe so eine Typdefinition auch mal verwendet (auch für eine dll),
    aber die sah bei mir in etwa so aus (auf Dein Problem angewandt):

    typedef int (__declspec(dllimport) TDPResult)(char*, char*);
    

    Ich bin mir aber nicht sicher, ob's daran liegt, aber einen Versuch
    ist es wert.

    Gruß,

    Alexander


Anmelden zum Antworten