Dynamischer Zugriff auf eine dll



  • __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



  • hallo,

    ron, das theater hättest du dir sparen können, steht nämlich alles im tutorial genaus beschrieben, das mit dem unterstrich, und das man die klammern weglässt, das näxte mal lieber gucken bevor du überheblich sagst, "das kann ich für mein problem nicht brauchen..."
    sonst vergeht mir die lust dir ein näxtes mal bei einem potentiellen weiteren problem noch mal helfen zu wollen, und die antworten solltest du auch genau durchlesen, das mit den klammern und dem unterstrich kam schon da hast du immer noch mit diesem komischen Ding "DbInit()" rumgemacht...

    mfg
    murphy



  • murphy schrieb:

    hallo,

    ron, das theater hättest du dir sparen können, steht nämlich alles im tutorial genaus beschrieben, das mit dem unterstrich, und das man die klammern weglässt, das näxte mal lieber gucken bevor du überheblich sagst, "das kann ich für mein problem nicht brauchen..."
    sonst vergeht mir die lust dir ein näxtes mal bei einem potentiellen weiteren problem noch mal helfen zu wollen, und die antworten solltest du auch genau durchlesen, das mit den klammern und dem unterstrich kam schon da hast du immer noch mit diesem komischen Ding "DbInit()" rumgemacht...

    mfg
    murphy

    Ja, im Nachhinein weiss ich, ich hab' einige Fehler begangen. Ich möchte mich für diese bei allen Betroffenen Entschuldigen und versuch natürlich mich aufjedenfall zu bessern!

    hab' die Definition jetzt auf

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

    abgeändert, bringt aber keine Änderung... 😞 Exception immernoch genau gleich... 😞



  • Bist Du Dir eigentlich sicher, daß die Signatur

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

    korrekt ist? Hast Du für die Dll eine Header-Datei oder sonst irgendeine
    Beschreibung?

    Gruß,

    Alexander



  • [edit]Doppelpost 😕 Wie kann man einen Beitrag eigentlich wieder löschen?[/edit]



  • Alexander Kempf schrieb:

    Bist Du Dir eigentlich sicher, daß die Signatur

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

    korrekt ist? Hast Du für die Dll eine Header-Datei oder sonst irgendeine
    Beschreibung?

    Gruß,

    Alexander

    ja einen header hab' ich und dort ist die Funktion so deklariert:

    EXPO1 DP_RESULT EXPO2 DPInit(LPSTR pDllName, LPSTR pInitSting);
    

    aber was LPSTR ist, hab' ich nirgends gefunden... 😞 und ich hab ein Delphi-Beispielk das funktioniert und dort werden PChar-Variablen gesendet und dann dachte ich, char* sei schon das richtige...
    Delaration in Delphi:

    function DPInit(pDllName, pInitSting : pchar) : TDPResult; stdcall;
     external 'PROF_DP.DLL';
    


  • Hallo,

    Aus der MSDN:

    LPSTR A 32-bit pointer to a character string



  • Braunstein schrieb:

    Hallo,

    Aus der MSDN:

    LPSTR A 32-bit pointer to a character string

    Oh, Vielen Dank, wusste ich nicht, die Borlandhilfe sagt nichts über LPSTR.
    Jetzt hab' ich alles (Deklarationen) auf LPSTR umgebogen, die Exception kommt aber immernoch 😞



  • roN schrieb:

    Delaration in Delphi:

    function DPInit(pDllName, pInitSting : pchar) : TDPResult; stdcall;
     external 'PROF_DP.DLL';
    

    Hast Du auch die Deklaration von TDPResult? Es muß nämlich schon alles
    stimmen.

    Gruß,

    Alexander



  • Alexander Kempf schrieb:

    Hast Du auch die Deklaration von TDPResult?

    ist das die Deklaration in Delphi? 😕

    type TDPResult =
    (
    	DP_NO_ERROR,                            // no error
    	DP_GENERIC_ERROR,			// generic error
    	DP_CALLED_TWICE,			// DP function have been called double (only with DPSetDispatchMessage())
    	DP_OPEN_FAILED,				// device (FDL) opening failed
    	DP_FDL_LOAD_FAILED,			// unable to load FDL library
    	DP_NOT_OPEN,				// FDL not opened
    	DP_THREAD_ENABLED,			// error, background thread enabled: function disabled
    	DP_NO_THREAD_ENABLED,		        // error, background thread is not enabled: function disabled
    	DP_OUT_OF_MEMORY,			// out of memory
    	DP_CONVERTER_FAILED,		        // PROFIBUS converter not found, failed or bad type
    	DP_ILL_ADDRESS,				// illegal DP slave address
    	DP_SAP_OPEN_FAILED,			// PROFIBUS SAP opening failed
    	DP_SLAVE_OPEN,				// slave is allread open
    	DP_SLAVE_NOT_OPEN,			// slave is not opened
    	DP_SLAVE_NOT_FOUND,			// slave not found
    	DP_ILLEGAL_CONFIG,			// illegal PROFIBUS configuration
    	DP_CFG_ERROR,				// sconfiguration error on startup
    	DP_PRM_ERROR,				// parameter error on startup
    	DP_CFG_AND_PRM_ERROR,		        // configuration and parameter error on startup
    	DP_BAD_LENGTH,				// data length incorrect
    	DP_INCOMPLETE,				// background operation initiated: use DPGetAsyncResult() for answer. High word holds operation ID */
    	DP_NORESULT				// no background operation finished DPGetAsyncResult()
    );
    


  • roN schrieb:

    ist das die Deklaration in Delphi? 😕

    Sieht für mich nicht so aus. Vielleicht solltest Du das auch mal
    in Deinen Code einbinden und als Rückgabetyp für Deine Funktion
    verwenden.

    Gruß,

    Alexander



  • Alexander Kempf schrieb:

    Vielleicht solltest Du das auch mal
    in Deinen Code einbinden und als Rückgabetyp für Deine Funktion
    verwenden.

    Und wie bieg' ich das auf C++ um?



  • roN schrieb:

    Und wie bieg' ich das auf C++ um?

    Per Copy&Paste



  • Alexander Kempf schrieb:

    Per Copy&Paste

    Jetzt hab' ich das so in den header unter public eingefügt, und der Compiler meint,"Typname erwartet"
    also mit copy &paste funktioniert das nicht einfach (oder ich hab's am falschen Ort eingefügt...)

    type TDPResult =
    (
        DP_NO_ERROR,                            // no error
        DP_GENERIC_ERROR,            // generic error
        DP_CALLED_TWICE,            // DP function have been called double (only with DPSetDispatchMessage())
        DP_OPEN_FAILED,                // device (FDL) opening failed
        DP_FDL_LOAD_FAILED,            // unable to load FDL library
        DP_NOT_OPEN,                // FDL not opened
        DP_THREAD_ENABLED,            // error, background thread enabled: function disabled
        DP_NO_THREAD_ENABLED,                // error, background thread is not enabled: function disabled
        DP_OUT_OF_MEMORY,            // out of memory
        DP_CONVERTER_FAILED,                // PROFIBUS converter not found, failed or bad type
        DP_ILL_ADDRESS,                // illegal DP slave address
        DP_SAP_OPEN_FAILED,            // PROFIBUS SAP opening failed
        DP_SLAVE_OPEN,                // slave is allread open
        DP_SLAVE_NOT_OPEN,            // slave is not opened
        DP_SLAVE_NOT_FOUND,            // slave not found
        DP_ILLEGAL_CONFIG,            // illegal PROFIBUS configuration
        DP_CFG_ERROR,                // sconfiguration error on startup
        DP_PRM_ERROR,                // parameter error on startup
        DP_CFG_AND_PRM_ERROR,                // configuration and parameter error on startup
        DP_BAD_LENGTH,                // data length incorrect
        DP_INCOMPLETE,                // background operation initiated: use DPGetAsyncResult() for answer. High word holds operation ID */
        DP_NORESULT                // no background operation finished DPGetAsyncResult()
    );
    

Anmelden zum Antworten