I have been trying to create a Wrapper for UDP functionality. Basically a DLL which can open, configure, send/recieve UDP packets, and close. I create a hidden window to handle UDP events and create a separate thread for the dialog processing.
The problem is, I can open and send, but after that, any other call I make crashes the app.
Here is the code...
I would appreciate it if someone could help me figure out what's wrong.
Thanks
-Vince
The problem is, I can open and send, but after that, any other call I make crashes the app.
Here is the code...
Code:
#COMPILE DLL #REGISTER NONE #INCLUDE "WIN32API.INC" #INCLUDE "WS2_32.INC" GLOBAL ghInstance AS DWORD GLOBAL pCALLBACK AS DWORD GLOBAL hThread AS DWORD GLOBAL hDlg AS DWORD TYPE UDP_OBJECT pCALLBACK AS DWORD IPAdd AS ASCIIZ * 20 PORTNum AS DWORD FILENum AS DWORD END TYPE %UDPMSG_BASE = %WM_USER+500 PMSG = PMSG_BASE + 800 '-------------------------------------------------------------------------------- ' ** Declarations ** '-------------------------------------------------------------------------------- DECLARE CALLBACK FUNCTION ShowDIALOG1Proc() DECLARE FUNCTION ShowDIALOG(BYVAL hParent AS DWORD) AS LONG DECLARE FUNCTION MyThread(BYVAL y AS DWORD) AS DWORD DECLARE SUB CustomCALLBACK(BYVAL Msg AS LONG) '------------------------------------------------------------------------------- ' Main DLL entry point called by Windows... ' FUNCTION LIBMAIN (BYVAL hInstance AS LONG, _ BYVAL fwdReason AS LONG, _ BYVAL lpvReserved AS LONG) AS LONG SELECT CASE fwdReason CASE %DLL_PROCESS_ATTACH 'Indicates that the DLL is being loaded by another process (a DLL 'or EXE is loading the DLL). DLLs can use this opportunity to 'initialize any instance or global data, such as arrays. ghInstance = hInstance ShowDialog (%Hwnd_Desktop) THREAD CREATE MyThread(ghInstance) TO hThread FUNCTION = 1 'success! CASE %DLL_PROCESS_DETACH 'Indicates that the DLL is being unloaded or detached from the 'calling application. DLLs can take this opportunity to clean 'up all resources for all threads attached and known to the DLL. THREAD CLOSE hThread TO hThread DIALOG END hDlg FUNCTION = 1 'success! CASE %DLL_THREAD_ATTACH 'Indicates that the DLL is being loaded by a new thread in the 'calling application. DLLs can use this opportunity to 'initialize any thread local storage (TLS). FUNCTION = 1 'success! CASE %DLL_THREAD_DETACH 'Indicates that the thread is exiting cleanly. If the DLL has 'allocated any thread local storage, it should be released. FUNCTION = 1 'success! END SELECT END FUNCTION '-------------------------------------------------------------------------------- ' ** CallBacks ** '-------------------------------------------------------------------------------- CALLBACK FUNCTION ShowDIALOG1Proc() DIM lParam AS LONG DIM Count AS LONG SELECT CASE CBMSG CASE PMSG IF pCALLBACK > 0 THEN lParam = CBLPARAM CALL DWORD pCALLBACK USING CustomCALLBACK(lParam) FUNCTION = 1 END IF ' Select Case lParam ' Case %FD_READ 'Data is available to be read from the socket. ' Case %FD_WRITE 'The socket is ready for data to be written. ' Case %FD_ACCEPT 'The socket is able to accept a new connection. ' Case %FD_CONNECT 'The connection has been established. ' Case %FD_CLOSE 'The socket has been closed. ' End Select END SELECT END FUNCTION FUNCTION MyThread(BYVAL y AS DWORD) AS DWORD LOCAL e AS LONG LOCAL x AS LONG DO DIALOG DOEVENTS TO e DIALOG GET SIZE hDlg TO x, x LOOP WHILE x 'When x& = 0, dialog has ended END FUNCTION '-------------------------------------------------------------------------------- ' ** Dialogs ** '-------------------------------------------------------------------------------- FUNCTION ShowDIALOG(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG LOCAL pIP AS LONG DIALOG NEW hParent, "UDP", 267, 182, 195, 102, %WS_POPUP _ '%WS_VISIBLE _ OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg DIALOG SHOW MODELESS hDlg, CALL ShowDIALOG1Proc TO lRslt DIALOG SHOW STATE hDlg, %SW_HIDE FUNCTION = lRslt END FUNCTION '------------------------------------------------------------------------------- ' Examples of exported Subs and functions... ' FUNCTION UDP_CREATE CDECL () EXPORT AS LONG FUNCTION = globalalloc(%GPTR, SIZEOF(UDP_OBJECT)) END FUNCTION FUNCTION UDP_SETIP CDECL(BYVAL pUDP_OBJECT AS UDP_OBJECT PTR, BYVAL IP AS STRING, BYVAL PortNum AS DWORD) EXPORT AS LONG ERRCLEAR @pUDP_OBJECT.IPAdd = IP @pUDP_OBJECT.PortNum = PortNum FUNCTION = ERR END FUNCTION FUNCTION UDP_CALLBACK CDECL(BYVAL pUDP_OBJECT AS UDP_OBJECT PTR, BYVAL pCALLBK AS DWORD) EXPORT AS LONG ERRCLEAR pCALLBACK = pCALLBK IF (@pUDP_OBJECT.FileNum > 0) AND (@pUDP_OBJECT.pCALLBACK > 0) THEN UDP NOTIFY @pUDP_OBJECT.FileNum, SEND RECV CLOSE TO hDlg AS PMSG END IF FUNCTION = ERR END FUNCTION FUNCTION UDP_OPEN CDECL(BYVAL pUDP_OBJECT AS UDP_OBJECT PTR) EXPORT AS LONG ERRCLEAR 'Auto Close any previous connection IF @pUDP_OBJECT.FileNum > 0 THEN UDP CLOSE @pUDP_OBJECT.FileNum @pUDP_OBJECT.FileNum = 0 @pUDP_OBJECT.pCALLBACK = 0 END IF @pUDP_OBJECT.FileNum = FREEFILE UDP OPEN PORT @pUDP_OBJECT.PortNum AS @pUDP_OBJECT.FileNum FUNCTION = ERR END FUNCTION FUNCTION UDP_CLOSE CDECL(BYVAL pUDP_OBJECT AS UDP_OBJECT PTR) EXPORT AS LONG ERRCLEAR 'Auto close previous connection IF @pUDP_OBJECT.FileNum > 0 THEN UDP CLOSE @pUDP_OBJECT.FileNum @pUDP_OBJECT.FileNum = 0 END IF GlobalFree (pUDP_OBJECT) FUNCTION = ERR END FUNCTION FUNCTION UDP_SENDDATA CDECL(BYVAL pUDP_OBJECT AS UDP_OBJECT PTR, BYVAL Packet AS STRING ) EXPORT AS LONG DIM pIP AS LONG ERRCLEAR 'Send Data IF @pUDP_OBJECT.FileNum > 0 THEN HOST ADDR @pUDP_OBJECT.IPAdd TO pIP UDP SEND @pUDP_OBJECT.FileNum, AT pIP, @pUDP_OBJECT.PortNum, Packet END IF FUNCTION = ERR SLEEP 1 END FUNCTION FUNCTION UDP_GETDATA CDECL(BYVAL pUDP_OBJECT AS UDP_OBJECT PTR, BYREF IPAdd AS LONG, BYREF PortNum AS LONG) EXPORT AS STRING LOCAL Buffer AS STRING LOCAL pPort AS LONG ERRCLEAR 'Get Data IF @pUDP_OBJECT.FileNum > 0 THEN UDP RECV @pUDP_OBJECT.FileNum , FROM IPAdd, PortNum, Buffer FUNCTION = Buffer EXIT FUNCTION END IF FUNCTION = "###" SLEEP 1 END FUNCTION
Thanks
-Vince
Comment