From 8c1f4d7bace6ff2c99d546cedaba890b349e88f8 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 16 Jan 2009 23:55:53 +0000 Subject: I...think that's a little better. Wow, function pointers in windows have a lot of problems. This may require a little more research, but basically, you can't just call them inline wherever you'd like. I managed to get it to work by providing simple one line wrapper functions for each function we acquired as a pointer. Crazy mess. Anyway, it should load the library just once now, and Bu::Socket looks a little bit cleaner, but not a heck of a lot. I also added some more docs and removed the author references. --- src/win32_compatibility.h | 110 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 34 deletions(-) (limited to 'src/win32_compatibility.h') diff --git a/src/win32_compatibility.h b/src/win32_compatibility.h index 2d3c52b..36613d1 100644 --- a/src/win32_compatibility.h +++ b/src/win32_compatibility.h @@ -8,12 +8,6 @@ #ifndef WIN32_COMPATIBILITY__H #define WIN32_COMPATIBILITY__H -#ifdef WIN32 - #define DYNLOAD DynamicWinsock2:: -#else - #define DYNLOAD -#endif - #ifdef WIN32 #ifdef __cplusplus @@ -36,37 +30,19 @@ extern "C" __result; })) #endif +#define decltype( ret, name, ... ) \ + typedef ret (__cdecl *FNDEF_DYN_ ##name)( __VA_ARGS__ ); \ + static FNDEF_DYN_ ##name _fnptr_ ##name; \ + static ret name( __VA_ARGS__ ) + __extension__ typedef int socklen_t; -namespace DynamicWinsock2 -{ - int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData); - int WSACleanup(void); - int WSAGetLastError(); - void inet_ntoa( Bu::FString &out, struct in_addr addr_in ); - unsigned long inet_addr( const char *s_in ); - int select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, const struct timeval *timeout); - SOCKET socket(int domain, int type, int protocol); - int ioctlsocket(SOCKET s, long cmd, u_long *argp); - u_short htons(u_short in); - u_long htonl(u_long in); - struct hostent *gethostbyname(const char *name); - void freeaddrinfo(struct addrinfo *ai); - int getaddrinfo( - const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res ); - int connect(SOCKET s, const struct sockaddr *serv_addr, int addrlen); - int getpeername(SOCKET s, struct sockaddr *name, int *namelen); - int setsockopt(SOCKET s, int level, int optname, - const char *optval, int optlen); - int bind(SOCKET s, const struct sockaddr *my_addr, int addrlen); - int listen(SOCKET s, int backlog); - SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen); - int recv( SOCKET s, char *buf, int len, int flags ); - int send( SOCKET s, const char *buf, int len, int flags ); - int DYN_FD_ISSET(SOCKET s, fd_set *set); +#ifdef gai_strerror +#undef gai_strerror +#endif +namespace Bu +{ class Winsock2 : public Bu::Singleton { friend class Bu::Singleton; @@ -75,11 +51,77 @@ namespace DynamicWinsock2 virtual ~Winsock2(); WSADATA wsaData; + HINSTANCE Ws2_32; public: + // decltype( return type, function name<, optional parameters> ) + decltype( int, WSAStartup, WORD, LPWSADATA ); + decltype( int, WSACleanup ); + decltype( int, WSAGetLastError ); + decltype( char *, inet_ntoa, struct in_addr ); + decltype( unsigned long, inet_addr, const char *s_in ); + decltype( int, select, int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, const struct timeval *timeout ); + decltype( SOCKET, socket, int domain, int type, int protocol ); + decltype( int, ioctlsocket, SOCKET s, long cmd, u_long *argp ); + decltype( u_short, htons, u_short in ); + decltype( u_long, htonl, u_long in ); + decltype( struct hostent *, gethostbyname, const char *name ); + decltype( void, freeaddrinfo, struct addrinfo *ai ); + decltype( int, getaddrinfo, const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res ); + decltype( int, connect, SOCKET s, const struct sockaddr *serv_addr, + int addrlen ); + decltype( int, getpeername, SOCKET s, struct sockaddr *name, + int *namelen ); + decltype( int, setsockopt, SOCKET s, int level, int optname, + const char *optval, int optlen ); + decltype( int, bind, SOCKET s, const struct sockaddr *my_addr, + int addrlen ); + decltype( int, listen, SOCKET s, int backlog ); + decltype( SOCKET, accept, SOCKET s, struct sockaddr *addr, + int *addrlen); + decltype( int, recv, SOCKET s, char *buf, int len, int flags ); + decltype( int, send, SOCKET s, const char *buf, int len, int flags ); + decltype( int, __WSAFDIsSet, SOCKET s, fd_set *set ); + + static char scode[15]; + static char *gai_strerror( int iCode ); }; }; +#ifdef FD_ISSET +#undef FD_ISSET +#endif + +#define bu_WSAStartup (*Bu::Winsock2::WSAStartup) +#define bu_WSACleanup (*Bu::Winsock2::WSACleanup) +#define bu_WSAGetLastError (*Bu::Winsock2::WSAGetLastError) +#define bu_inet_ntoa (*Bu::Winsock2::inet_ntoa) +#define bu_inet_addr (*Bu::Winsock2::inet_addr) +#define bu_select (*Bu::Winsock2::select) +#define bu_socket (*Bu::Winsock2::socket) +#define bu_ioctlsocket (*Bu::Winsock2::ioctlsocket) +#define bu_htons (*Bu::Winsock2::htons) +#define bu_htonl (*Bu::Winsock2::htonl) +#define bu_gethostbyname (*Bu::Winsock2::gethostbyname) +#define bu_freeaddrinfo (*Bu::Winsock2::freeaddrinfo) +#define bu_getaddrinfo (*Bu::Winsock2::getaddrinfo) +#define bu_connect (*Bu::Winsock2::connect) +#define bu_getpeername (*Bu::Winsock2::getpeername) +#define bu_setsockopt (*Bu::Winsock2::setsockopt) +#define bu_bind (*Bu::Winsock2::bind) +#define bu_listen (*Bu::Winsock2::listen) +#define bu_accept (*Bu::Winsock2::accept) +#define bu_recv (*Bu::Winsock2::recv) +#define bu_send (*Bu::Winsock2::send) +#define bu___WSAFDIsSet (*Bu::Winsock2::__WSAFDIsSet) + +#define FD_ISSET (*Bu::Winsock2::__WSAFDIsSet) +#define bu_gai_strerror Bu::Winsock2::gai_strerror + +#undef decltype + #endif /* WIN32 */ #endif -- cgit v1.2.3