Dynamischer Zugriff auf eine dll



  • Braunstein schrieb:

    Sag mal, hast du eigentlich die zugehörige prof_dp.lib mit in dein Projekt eingebunden (für statische Bindung)? Falls du sie nicht hast kansst du sie dir mit Hilfe von ImpLib erzeugen.

    Klar, hab' ich erzeugt und eingebunden.

    Und die Header-Datei wurde mit geliefert.



  • roN schrieb:

    Klar, hab' ich erzeugt und eingebunden.
    Und die Header-Datei wurde mit geliefert.

    😕 Linkst Du eigentlich jetzt statisch oder dynamisch?
    Mir kommt's so vor, als ob Du da einen Mischmasch hast.

    Gruß,

    Alexander



  • Alexander Kempf schrieb:

    roN schrieb:

    Klar, hab' ich erzeugt und eingebunden.
    Und die Header-Datei wurde mit geliefert.

    😕 Linkst Du eigentlich jetzt statisch oder dynamisch?
    Mir kommt's so vor, als ob Du da einen Mischmasch hast.

    Gruß,

    Alexander

    Mischmasch hab' ich keinen, ich hab' zwei Versionen, zum einen unterstützt mich jemand aus der borland Newsgroup bei der dynamischen und ihr hier, unterstützen mich bei der statischen Einbindung. Mir ist schlussendlich egal, wie ich darauf zugreiffen kann, hauptsache es funktioniert mal...



  • roN schrieb:

    (...) und ihr hier, unterstützen mich bei der statischen Einbindung.

    😕 Wie paßt das zum Thema des Threads?



  • Alexander Kempf schrieb:

    roN schrieb:

    (...) und ihr hier, unterstützen mich bei der statischen Einbindung.

    😕 Wie paßt das zum Thema des Threads?

    Gar nicht, am anfang war die hilfe zur dynamischen Einbindung da, aber dann hat Braunstein nach dem Linker Error gefragt den ich bei der statischen Einbindung bekomme....so war das...
    schau sonst mal auf den Beitrag vom 14. Okt 2003 um 13:13.



  • roN schrieb:

    am anfang war die hilfe zur dynamischen Einbindung da

    Also bei meinen bisherigen Antworten bin ich immer von einer dynamischen Einbindung ausgegangen.
    Ich habe jetzt noch mal nachgeschaut, wie ich damals die Siemens-Dll dynamisch eingebunden hatte.
    Das sieht bei mir so ähnlich aus (die uninteressanten Sachen habe ich weggelassen):

    Der Header

    class MyClass:
    {
    public:
       MyClass(void);
    private:
       HINSTANCE dllHandle;
       typedef int (__declspec(dllimport) load_tool_dll)(char,char *,adr_table_type *);
       load_tool_dll *load_tool;
    };
    

    Und die Implementierung

    MyClass::MyClass(void)
    {
       dllHandle = LoadLibrary("eine_dll.dll");
       if (!dllHandle)
          throw Exception("Fehler beim Laden der Dll");
       load_tool = (load_tool_dll*) GetProcAddress(dllHandle, "load_tool");
       if (!load_tool)
          throw Exception("Fehler beim Laden der Dll-Funktion \"load_tool\"");
    }
    

    Und das stand in der mitgelieferten .h-Datei, die ich aber nicht eingebunden habe

    typedef struct
    	{
    	unsigned char  adr;
    	unsigned char  segmentid;
    	unsigned char  slotno;
    	unsigned char  rackno;
    	} adr_table_type;
    int WINAPI load_tool(char,char *,adr_table_type *);
    

    Vielleicht kannst Du ja das auf Dein Problem anwenden?

    Gruß,

    Alexander



  • Ja, danke konnte bisschen was abschauen und bin weiter gekommen aber jetzt motzt der Compiler wieder und meint "Aufruf einer Nicht-Funktion" und ich weiss nicht warum öchz ich hab' mein code ein bisschen abgeändert desshalb füg ich hier wieder etwas ein:
    Die Klassen cpp:

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #ifdef _WIN32
        #include <windows.h>
    #endif
    #include "prof_dp.h"
    #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);
    
    //typedef int (CALLBACK *TDPResult)(char*, char*);
    DP_RESULT pDPInit;
    HINSTANCE hInstance;
    
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    __fastcall TProfibus::TProfibus()
    {
    	/*ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    	if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
    	{
    
    	}*/
    hInstance = ::LoadLibrary("prof_dp.dll");
    if (hInstance)
      {
      pDPInit = (DP_RESULT)::GetProcAddress(hInstance, "DPInit");
      if (!pDPInit)
        {
         Application->MessageBox(AnsiString("Fehler bei der Adressierung der Funktion \"pDPInit\"\nFehler#:" + AnsiString(GetLastError())).c_str(), "Fehler",16);
        }
      }
    }
    //---------------------------------------------------------------------------
    __fastcall TProfibus::~TProfibus(void)
    {
    FreeLibrary(hInstance);                 // allozierter Speicher für dll wieder freigeben
    }
    //---------------------------------------------------------------------------
    void __fastcall TProfibus::Init(int SlaveID_int, unsigned int uPort)
    {                                     // einstellen des COM-Ports und der Busgeschwinigkeit
    LPSTR pIni="COM1,SA1,01,00,60,09,C0,12,33,00,7D,7E,01,03,00,10,08,94,00,90,01,20,03,00,04,2C,01,1E,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)// FEHLER! "Aufruf einer Nicht-Funktion"
     ShowMessage("Juhuuuuuuuuuuuuuuuiiiiiiiiiiiiiii!!!!!!!!!!!!!");
     Tools::SetAllComponents(Main_Frm, true, crArrow);
     Main_Frm->Memo1->Lines->Add(pDPInit(pDll,pIni));
     }
    
    }
    //---------------------------------------------------------------------------
    static bool InitCommunication(unsigned int uPort)
    {
    return true;
    }
    //---------------------------------------------------------------------------
    

    Der Header:

    //---------------------------------------------------------------------------
    #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 (__declspec(dllimport) TDPResult)(LPSTR, LPSTR);
    //       typedef int (TDPResult)(LPSTR, LPSTR);
    //       typedef int (*TDPResult)(char*, char*);
    
    protected:
    };
    //---------------------------------------------------------------------------
    #endif
    

    Der Header der mitgeliefert wurde:

    /*********************************************************************
     *                                                                   *
     *                       Bihl+Wiedemann GmbH                         *
     *                                                                   *
     *                                                                   *
     *       project: Profibus Master Simulator                          *
     *   module name: prof_dp.h                                          *
     *        author: Ulrich Holeschak                                   *
     *          date: 06/11/2000                                         *
     *                                                                   *
     *      RCS info:                                                    *
     *         $Date: 2002/07/23 08:10:15 $
     *       $Locker:  $
     *     $Revision: 1.4 $
     *        $State: Exp $
     *                                                                   *
     *       history: 1.0 new                                            *
     *       history: 2.0 with DPE                                       *
     *                                                                   *
     *   description: PROFIBUS DP and DPE state machine                  *
     *                Operates with several FDL interfaces               *
     *                                                                   *
     *********************************************************************/
    
    /*********************************************************************
    	Defines
     *********************************************************************/
    
    #ifndef _PROF_DP_H
    #define _PROF_DP_H
    
    #include "dpe_def.h"	/* definitions for dpe */
    
    /* definition of callbacks */
    #ifdef _WIN32
    #define EXPO1
    #define EXPO2 CALLBACK
    #else
    #define EXPO1
    #define EXPO2 CALLBACK _export
    #endif
    
    /* message types for Notification messages (WPARAM) */
    /* Notification messages hold these values in WPARM to distinguish the message types */
    #define	MSG_TYPE_ASYNC		0x0001		/* async. operation finished, LPARAM=holds operation ID */
    #define	MSG_TYPE_DPCYCLE	0x0002		/* This message is sent, after completion of one PROFIBUS DP cycle */
    #define	MSG_TYPE_DPE		0x0004		/* message on DPE confirmation or indication */
    
    /* thise macros help to analyse the functions result value DP_RESULT */
    #define	DP_RESULT_CODE(_rcode) (_rcode & 0xFFFF)			/* result of code of operation */
    #define	DP_RESULT_ID(_rcode) ((_rcode>>16) & 0xFFFF)		/* result ID of async operation */
    															/* (only for DP_INCOMPLETE) */
    
    /*********************************************************************
    	Typedefs
     *********************************************************************/
    
    /* Data structure for cyclic PROFIBUS DP operations */
    typedef struct
    {
    	unsigned char 	NormParameters [7];		/* set on startup: norm parameter. Ident number is read from slave */
    	unsigned char 	UserParamLength;		/* set on startup: user parameter length */
    	unsigned char 	UserParameters [248];	/* set on startup: user parameter */
    	unsigned char 	ConfigLength;			/* set on startup: configuration length, 0==read config from slave */
    	unsigned char 	Configuration  [256];	/* set on startup: configuration */
    	unsigned char 	OutputLength;			/* automatically set by DPOpenSlave() : output length */
    	unsigned char 	OutputData     [256];	/* set on startup and with DPWriteSlaveData(): output data to send */
    	unsigned char 	InputLength;			/* receive: input length */
    	unsigned char 	InputData      [256];	/* receive: input data */
    	unsigned char 	NormDiagnosis  [6];		/* receive: norm diagnosis */
    	unsigned char 	UserDiagLength;			/* receive: user diag length */
    	unsigned char 	UserDiagnosis  [256];	/* receive: user diagnosis */
    	bool			bCommunicate;			/* receive: slave is communicating (TRUE) */
    	bool			bOperate;				/* receive: slave is in state operate (TRUE) */
    	bool			bNewDiag;				/* receive: new diag data ,cleared by DPReadSlaveData() */
    } DP_DATA;
    
    /* Result codes for functions */
    typedef enum
    {
    	DP_NO_ERROR = 0x0000,		/* 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() */
    } _DP_RESULT;
    
    /* type of result code */
    typedef unsigned long	DP_RESULT;
    
    /* result codes from async. operations */
    typedef enum
    {
    	CMD_OPEN = 0,						/* command open slave */
    	CMD_CLOSE,							/* command close slave */
    	CMD_GETCFG,							/* command get cfg */
    	CMD_SENDPRM,						/* command send parameter */
    	CMD_IDENTIFY,						/* command get ident number */
    	CMD_ADDR,							/* command change address */
    } CMD_TYPES;
    
    /* structure for async. command data by DPGetAsyncResult() */
    typedef struct
    {
    	CMD_TYPES		uCmd;					/* initiate command type */
    	unsigned int	uID;					/* id code of operation (high byte of DP_INCOMPLETE result) */
    	DP_RESULT		ResultCode;				/* result error code of operation */
    											/* union holding result for serveral commands: */
    	union
    	{
    		struct								/* result of DPOpenSlave() CMD_OPEN */
    		{
    			DP_DATA			pDpData;		/* result slave data */
    		} Open;
    		struct								/* result of DPGetCfg() CMD_GETCFG */
    		{
    			unsigned char	ucLength;		/* result config length */
    			unsigned char	Buffer[256];	/* result configuration */
    		} GetCfg;
    		struct								/* result of DPIdentifySlave() CMD_IDENTIFY */
    		{
    			unsigned int	uIdentNumber;	/* result ident number */
    		} Ident;
    	} Data;
    } ASYNC_RESULT;
    
    /*********************************************************************
    	Prototypes
     *********************************************************************/
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPInit(LPSTR pDllName, LPSTR pInitSting);
     *
     *  description:
     *		Init DP and FDL module.
     *
     *  parameters:
     *		pDllName: name of FDL dll
     *				NULL=RS232 (fdlrs.dll) (default)
     *				Options:
     *					"fdlrs": Operation with serial PROFIBUS UART
     *					"fdlcp": Operation with SIEMENS Profibus cards. SINEC driver must be installed first.
     *							Tested only with CP5412A2 and SOFTNET DP!!!
     *
     *		pInitSting: Init string for FDL.
     *					fdlrs: Com port "COMx", NULL=="COM2" (default)
     *					fdlcp: Name of PROFIBUS card Entry Point, NULL=="/CP_L2_1:/FLC" (default)
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPInit(LPSTR pDllName, LPSTR pInitSting);
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPExit(void);
     *
     *  description:
     *		Exit DP and FDL module.
     *
     *  parameters:
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPExit(void);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPSetDispatchMessage (int (CALLBACK* DispatchFunction)(MSG FAR *));
     *
     *  description:
     *		Set dispatcher for messages during communication.
     *		Warning: Use this function carefully, because there is the danger of
     *				multiple DP Function calls. We recommed to use DPEnableCommThread()
     *				for background communication. In thise case never use DPSetDispatchMessage()!
     *
     *  parameters:
     *		DispatchFunction: Callback function for message dispatches (Normally with DispatchMessage())
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPSetDispatchMessage (int (CALLBACK* DispatchFunction)(MSG FAR *));
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPSethWnd (HWND hWnd);
     *
     *  description:
     *		Set window handle of main window. Only necessary if fdlcp is used
     *		and DPEnableCommThread() is NOT activated!
     *
     *  parameters:
     *		hWnd: Main window handle
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPSethWnd (HWND hWnd);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPIdentifySlave (unsigned char ucSlvAddr, unsigned int FAR *puIdentNumber, BOOL bNoRetry);
     *
     *  description:
     *		Get ident number of specified slave. This function could also be used to find
     *		Slaves on the bus. The FDL has no retry for this operation.
     *
     *  parameters:
     *		ucSlvAddr: Address of slave to get ident number from (0..126)
     *		puIdentNumber: Pointer to buffer for result ident number.
     *				If DPEnableCommThread() is activated this parameter is not used (could be NULL)
     *				In this case the result code is DP_INCOMPLETE (High byte is ID)
     *				and the result is received with DPGetAsyncResult()
     *		bNoRetry: TRUE: No retry on fdl layer (fast!)
     *
     *  returns:
     *		_DP_RESULT error code
     *		If DPEnableCommThread() is activated the result code is DP_INCOMPLETE (High byte is ID)
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPIdentifySlave (unsigned char ucSlvAddr, unsigned int FAR *puIdentNumber, BOOL bNoRetry);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPChangeAddress(unsigned char ucOldAddr, unsigned char ucNewAddr);
     *
     *  description:
     *		Change the address of the specified slave.
     *
     *  parameters:
     *		ucOldAddr: Current slave address (0..126)
     *		ucNewAddr: New slave address (0..126)
     *
     *  returns:
     *		_DP_RESULT error code
     *		If DPEnableCommThread() is activated the result code is DP_INCOMPLETE (High byte is ID)
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPChangeAddress(unsigned char ucOldAddr, unsigned char ucNewAddr);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPGetCfg(unsigned char ucSlvAddr, unsigned char FAR *pBuffer, unsigned char FAR *pucLength);
     *
     *  description:
     *		Get the default configuration of the specified slave.
     *
     *  parameters:
     *		ucSlvAddr: Slave address (0..126)
     *		pBuffer: Buffer for Config result. Must have size 256.
     *		pucLength: Result length of configuration
     *				If DPEnableCommThread() is activated pBuffer and pucLength are not used (could be NULL)
     *				In this case the result code is DP_INCOMPLETE (High byte is ID)
     *				and the result is received with DPGetAsyncResult()
     *
     *  returns:
     *		_DP_RESULT error code
     *		If DPEnableCommThread() is activated the result code is DP_INCOMPLETE (High byte is ID)
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPGetCfg(unsigned char ucSlvAddr, unsigned char FAR *pBuffer, unsigned char FAR *pucLength);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPSendPrm(unsigned char ucSlvAddr, DP_DATA FAR * pDpData)
     *
     *  description:
     *		Send extra parameters to the specified slave.
     *
     *  parameters:
     *		ucSlvAddr: Slave address (0..126)
     *		pDpData: Data Structure with new parameter data for the slave
     *					Update NormParameters and UserParameters
     *
     *  returns:
     *		_DP_RESULT error code
     *		If DPEnableCommThread() is activated the result code is DP_INCOMPLETE (High byte is ID)
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPSendPrm(unsigned char ucSlvAddr, DP_DATA FAR * pDpData);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPOpenSlave(unsigned char ucSlvAddr, DP_DATA FAR * pDpData, unsigned int uOpenTimeout);
     *
     *  description:
     *		Open the communication with the specified slave
     *
     *  parameters:
     *		ucSlvAddr: Slave address (0..126)
     *		pDpData: Structure with init data. Look at DP_DATA with fields to initialize.
     *				We recommend to init all unsued fields with 0. After function return date will be updated.
     *				If DPEnableCommThread() is activated the update data is received with DPGetAsyncResult().
     *				In this case the result code is DP_INCOMPLETE (High byte is ID).
     *		uOpenTimeout: Timeout in sec. for slave initialisation. If 0 is specified, the result
     *				of initialisation is not tested. But if thes salve doesn't exit, an error returns.
     *
     *  returns:
     *		_DP_RESULT error code
     *		If DPEnableCommThread() is activated the result code is DP_INCOMPLETE (High byte is ID)
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPOpenSlave(unsigned char ucSlvAddr, DP_DATA FAR * pDpData, unsigned int uOpenTimeout);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPCloseSlave(unsigned char ucSlvAddr);
     *
     *  description:
     *		Close the communication with the specified slave
     *
     *  parameters:
     *		ucSlvAddr: Slave address (0..126)
     *
     *  returns:
     *		_DP_RESULT error code
     *		If DPEnableCommThread() is activated the result code is DP_INCOMPLETE (High byte is ID)
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPCloseSlave(unsigned char ucSlvAddr);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPReadSlaveData(unsigned char ucSlvAddr, DP_DATA FAR * pDpData, BOOL bResetDiag);
     *
     *  description:
     *		Read the operation data of the given slave.
     *
     *  parameters:
     *		ucSlvAddr: Slave address (0..126)
     *		pDpData: Buffer for result data.
     *		bResetDiag: If this value is TRUE, bNewDiag will be reset after reading.
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPReadSlaveData(unsigned char ucSlvAddr, DP_DATA FAR * pDpData, BOOL bResetDiag);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPWriteSlaveData(unsigned char ucSlvAddr, DP_DATA FAR * pDpData);
     *
     *  description:
     *		Write new output data to the given slave buffer.
     *		Only the output data field of DP_DATA is used.
     *
     *  parameters:
     *		ucSlvAddr: Slave address (0..126)
     *		pDpData: Buffer with output data. If the output length is invalid an error returns.
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPWriteSlaveData(unsigned char ucSlvAddr, DP_DATA FAR * pDpData);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPDoSingleComm(void);
     *
     *  description:
     *		Initiate a single communication on the PROFIBUS.
     *		If DPEnableCommThread() is activated this function is disabled.
     *		In this case communication is done by the background thread.
     *
     *  parameters:
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPDoSingleComm(void);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPDoCycleComm(void);
     *
     *  description:
     *		Initiate a complete PROFIBUS cycle. Communication is done
     *		with all opened slaves.
     *		If DPEnableCommThread() is activated this function is disabled.
     *		In this case communication is done by the background thread.
     *
     *  parameters:
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPDoCycleComm(void);
    
    #ifdef _WIN32
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPEnableCommThread(BOOL bEnable);
     *
     *  description:
     *		Enable background communication thread.
     *		If enabled, most functions work acyclic and return DP_INCOMPLETE.
     *		The operation result is reveived with DPGetAsyncResult()
     *
     *  parameters:
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPEnableCommThread(BOOL bEnable);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPSetUserMsg(HWND hNotifyWnd, DWORD dwThreadID, UINT uNotifyMsg, unsigned int uMsgMask);
     *
     *  description:
     *		Enable notification messages if DPEnableCommThread()
     *		is activated.
     *
     *  parameters:
     *		hNotifyWnd: Window handle with window to notify. IF this parameter is NULL
     *				dwThreadID will be used insted.
     *		dwThreadID: ID of thread for message totification. The messages will be send with
     *				Post ThreadMessage to this thread.
     *		uNotifyMsg: Nofification message. Best get this value with  RegisterWindowMessage().
     *		uMsgMask: Mask for messages to enable. Possible values can be a combination of
     *			MSG_TYPE_ASYNC		async. operation finished, LPARAM=holds operation ID
     *			MSG_TYPE_DPCYCLE	This message is sent, after completion of one PROFIBUS DP cycle
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPSetUserMsg(HWND hNotifyWnd, DWORD dwThreadID, UINT uNotifyMsg, unsigned int uMsgMask);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPGetAsyncResult(ASYNC_RESULT *pAsyncResult);
     *
     *  description:
     *		Get the result of an async. backgound operation.
     *		Only possible if DPEnableCommThread() is enabled.
     *
     *  parameters:
     *		pAsyncResult: Buffer for async result values. Look at ASYNC_RESULT for
     *				nearer informations.
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPGetAsyncResult(ASYNC_RESULT *pAsyncResult);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPECreateConnection(unsigned long *pC_Ref);
     *
     *  description:
     *		Create a new connection for DPE operation
     *		Only possible if DPEnableCommThread() is enabled.
     *
     *  parameters:
     *		pC_Ref: Buffer for result reference handle
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPECreateConnection(unsigned long *pC_Ref);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPEDestroyConnection(unsigned long C_Ref);
     *
     *  description:
     *		Destroy connection created with DPECreateConnection.
     *		Important: If possible, abort the communication over this
     *					C_Ref before closing the connection.
     *		Only possible if DPEnableCommThread() is enabled.
     *
     *  parameters:
     *		pC_Ref: reference handle form DPECreateConnection
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPEDestroyConnection(unsigned long C_Ref);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPESendRequest(DPE_REQUEST_INFO *pRequestInfo);
     *
     *  description:
     *		Send a request to the dpe staemachine. For request types
     *		look in pde_def.h
     *		Only possible if DPEnableCommThread() is enabled.
     *
     *  parameters:
     *		pRequestInfo: information about DPE request
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPESendRequest(DPE_REQUEST_INFO *pRequestInfo);
    
    /*************************************************************
     *
     *  EXPO1 DP_RESULT EXPO2 DPEReadResult(DPE_RESULT_INFO *pResultInfo);
     *
     *  description:
     *		Get Result from the dpe statemachine. This can be ither a
     *		confirmation to a request a spantaneous indication.
     *		So call this function very often to response from a message
     *		of type MSG_TYPE_DPE. (See DPSetUserMsg)
     *		Only possible if DPEnableCommThread() is enabled.
     *
     *  parameters:
     *		pResultInfo: information about DPE result
     *
     *  returns:
     *		_DP_RESULT error code
     */ 
    
    EXPO1 DP_RESULT EXPO2 DPEReadResult(DPE_RESULT_INFO *pResultInfo);
    
    /*************************************************************
     *
     *  EXPO1 BOOL EXPO2 WhichConvFeature(unsigned char feature);	/* Checks the plugged dongle 
     *
     *  description:
     *		called with feature:
     *			0x01	:= expensive
     *			0x02	:= DPV1
     *			0x04	:= master addressable
     *		
     *	returns: TRUE  for detected	
     *	 		 FALSE for not detected	
     *
     *
     */ 
    //EXPO1 BOOL EXPO2 WhichConvFeature(unsigned char feature);	/* Checks the plugged dongle */
    EXPO1 BOOL EXPO2 WhichConvFeature(unsigned char feature, LPSTR com);
    #endif
    
    #endif /*_PROF_DP_H */
    

    [edit] Code aktualisiert[/edit]



  • Mein Vorschlag:
    Den include von "prof_dp.h" rausnehmen, .lib-Datei rausnehmen (also dynamisch einbinden)

    Im Konstruktor

    __fastcall TProfibus::TProfibus()
    {
      // ...
      hInstance = ::LoadLibrary("prof_dp.dll");
      if (hInstance)
      {
        pDPInit = (DPInitDll*)::GetProcAddress(hInstance, "DPInit");
        if (!pDPInit)
        {
          // Fehlermeldung...
        }
      }
    }
    

    Der Header:

    //---------------------------------------------------------------------------
    #ifndef TProfibusH
    #define TProfibusH
    
    //---------------------------------------------------------------------------
    class TProfibus
    {
    public:
           __fastcall TProfibus(void);
           __fastcall ~TProfibus(void);
           void __fastcall Init(int SlaveID_int, unsigned int uPort);
    
    private:
       typedef DP_RESULT (__declspec(dllimport) DPInitDLL)(LPSTR, LPSTR); 
       DPInitDll* pDPInit; 
    };
    //---------------------------------------------------------------------------
    #endif
    

    Probier's halt mal aus. Ich weiß nicht, ob man die Makros EXPO1 und EXPO2 un-
    bedingt braucht. Wenn's so nicht funktioniert, kannst Du die ja auch noch ein-
    binden.

    Gruß,

    Alexander



  • Dann kommt im Header bei

    typedef DP_RESULT (__declspec(dllimport) DPInitDLL)(LPSTR, LPSTR);
    

    der Fehler:
    **
    [C++ Fehler] TProfibus.h(14): E2091 Funktionen können keine Arrays und Funktionen zurückliefern.
    **



  • Dann ändere mal den Rückgabetyp des Dll-Funktionstyps so:

    typedef unsigned long (__declspec(dllimport) DPInitDLL)(LPSTR, LPSTR);
    

    Gruß,

    Alexander



  • Okay, das geht dann schonmal aber dann meldet der Compiler bei

    DPInitDll* pDPInit;
    

    [C++ Fehler] TProfibus.h(15): E2303 Typname erwartet



  • Ich sag mal nur DPInitDLL != DPInitDll



  • Braunstein schrieb:

    Ich sag mal nur DPInitDLL != DPInitDll

    Allerdings... 😉



  • Braunstein schrieb:

    Ich sag mal nur DPInitDLL != DPInitDll

    *hUUUUUUUUUUUUUUUUUps* Sorry... 🤡 aber jetzt gibts folgendes in der TProfibus.cpp:

    //typedef int (CALLBACK *TDPResult)(char*, char*);
    DP_RESULT pDPInit;   //Compiler_Fehler:Hier kommt Fehler in der Deklarationssyntax
    HINSTANCE hInstance;
    


  • Ist der Typ DP_RESULT zu diesem Zeitpunkt schon bekannt ? Abgesehen davon, wozu brauchst du diese Variable überhaupt. Deinen Pointer auf die Funktion musst du ja wohl so "DPInitDLL *pDPInit;" deklarieren.



  • Braunstein schrieb:

    Deinen Pointer auf die Funktion musst du ja wohl so "DPInitDLL *pDPInit;" deklarieren.

    ah, okay, ich sehe ich lerne in diesem Fallk eine ganze Menge dazu! Vielen Dank an dich oder an euch!!!!
    hab' jetzt folgendes:

    DPInitDLL *pDPInit;
    

    und der Compiler meint:
    **
    [C++ Fehler] TProfibus.cpp(25): E2141 Fehler in der Deklarationssyntax
    **



  • roN schrieb:

    hab' jetzt folgendes:

    DPInitDLL *pDPInit;
    

    und der Compiler meint:
    **
    [C++ Fehler] TProfibus.cpp(25): E2141 Fehler in der Deklarationssyntax
    **

    Ist das in Deiner .cpp-Datei? Eigentlich ist das doch schon im Header
    deklariert.

    Gruß,

    Alexander



  • Alexander Kempf schrieb:

    Ist das in Deiner .cpp-Datei? Eigentlich ist das doch schon im Header
    deklariert.

    Ganz korrekt, wo hab' ich bloss meinen Kopf *such* 😕 ... Naja, Danke für den Hinweis.
    Jetzt nächstes Problem: Ich hab in meiner cpp folgendes:

    pDPInit = (DP_RESULT)::GetProcAddress(hInstance, "DPInit");
    

    der Compiler:[C++ Fehler] TProfibus.cpp(40): E2451 Undefiniertes Symbol 'DP_RESULT'
    weil ich ja die include-Anweisung mit dem prof_dp.h-header rausgenommen habe...



  • Na du stehst wohl heute ein bischen neben dir. 😉
    Der Typ deiner Funktion ist doch nicht DP_RESULT sondern DPInitDLL*.



  • Braunstein schrieb:

    Der Typ deiner Funktion ist doch nicht DP_RESULT sondern DPInitDLL*.

    ... wie ich ja bereits in einer meiner früheren Beiträge geschrieben hatte...
    (mal abgesehen von Groß-/Kleinschreibung 😉 )


Anmelden zum Antworten