www.digitalmars.com         C & C++   DMDScript  

c++.windows.32-bits - 32 bit dll compiling part 2

reply Janne Naukkarinen <kiviapaja hotmail.com> writes:
This is 32-bit DLL compiling.


 From kiviapaja hotmail.com

Why next example fails?

dmc -mn -WD ../gwinsock.cpp -w -D__DMC__ -Dgwinsock_main  kernel32.lib 
user32.lib gdi32.lib comdlg32.lib wsock32.lib > err2.txt


link gwinsock,,,kernel32+user32+gdi32+comdlg32+wsock32,gwinsock/noi;

OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved
   
OPTLINK : Warning 148: USE16/USE32 Mismatch : DGROUP
F:\DM\BIN\..\lib\SNN.lib(dllstart) 
 Error 83: Illegal frame on start address 
OPTLINK : Warning 174: 32-bit Segments Inappropriate for 16-bit Segmented 
output 
gwinsock.obj(gwinsock) 
 Error 116: NEAR call to IMPORT at Relative 00025H  from
 Segment _TEXT
 FRAME  = Frame of Group FLAT 0000
 TARGET = External Symbol _WSAStartup 8 00000H 
 FIXUPP Type = 32-bit Conditional JMP

--- errorlevel 2

Is this from source code or .def

My def is like this:

LIBRARY gwinsock
DESCRIPTION 'GWinSock -- socket wrapper dll' 
EXETYPE WINDOWS
EXPORTS
_gensock_close  1
_gensock_connect  2
_gensock_getchar  3
_gensock_gethostname  4
_gensock_put_data  5
_gensock_put_data_buffered  6
_gensock_put_data_flush  7


My source is like this

------- gwinsock.cpp ------------


// -*- C++ -*-
// generic socket DLL, winsock version
// disclaimer:  a C programmer wrote this.

// $Id: gensock.cpp 1.151 2004/12/25 22:07:10 NooN Exp $
// $Id: gensock.cpp 1.15 1994/11/23 22:38:10 rushing Exp $

#include <windows.h>

#include <string.h>
#include <ctype.h>

extern "C"
{
#include <winsock.h>
#include "gwinsock.h"
}


#ifdef _DEBUG
	 #ifndef __BORLANDC__
					  #define _CRTDBG_MAP_ALLOC
						#include <stdlib.h>
						#include <crtdbg.h>
			#else
						#include <stdlib.h>
			#endif
#else
  #include <stdlib.h>
#endif



//MDS increased buffer from 512 19991214
#define SOCKET_BUFFER_SIZE  1500

// This is for NT 
HANDLE  dll_module_handle;
#define GET_CURRENT_TASK    dll_module_handle
#define TASK_HANDLE_TYPE    HANDLE




//
// 
-------------------------------------------------------------------------
--
// container for a buffered SOCK_STREAM.

class connection
{
private:
    SOCKET          the_socket;
	 char *          in_buffer;
    char *          out_buffer;
    unsigned int    in_index;
	 unsigned int    out_index;
	 unsigned int    in_buffer_total;
	 unsigned int    out_buffer_total;
	 unsigned int    last_winsock_error;
	 TASK_HANDLE_TYPE owner_task;
	 fd_set          fds;
	 struct timeval  timeout;

public:

	 connection (void);
	 ~connection (void);

	 int       get_connected (char far * hostname, char far * 
service);
	 SOCKET    get_socket(void) { return (the_socket); }
	 TASK_HANDLE_TYPE get_owner_task(void) { return (owner_task); }
	 int       get_buffer(int wait);
	 int       close (void);
	 int       getchar (int wait, char far * ch);
	 int       put_data (char far * data, unsigned long length);
	 int       put_data_buffered (char far* data, unsigned long 
length);
	 int       put_data_flush (void);
};

//
//-----------------------------------------------------------------------
----
// we keep lists of connections in this class

class connection_list
{
private:
    connection *        data;
    connection_list *   next;
    
public:
    connection_list   (void);
    ~connection_list  (void);
    void push         (connection & conn);
    
    // should really use pointer-to-memberfun for these
    connection * find (SOCKET sock);
    int how_many_are_mine (void);
    
    void remove       (socktag sock);
};




connection_list global_socket_list;
int network_initialized;


//int  init_winsock (void);
//void deinit_winsock (void);

//
//
//


#ifdef _DEBUG
void complain (char * message)
{
    OutputDebugString (message);
}
#else
void complain (char * message)
{
    MessageBox (NULL, message, "GWINSOCK.DLL Error", MB_OK|MB_ICONHAND);
}
#endif


//-----------------------------------------------------------------------
----
//
//

int init_winsock(void)
{
    int retval;
    WSADATA winsock_data;
    WORD version_required = 0x0101; // Version 1.1 
    
    retval = WSAStartup (version_required, &winsock_data);
    
    switch (retval) 
    {
    case 0:
        // successful 
        break;
    case WSASYSNOTREADY:
        return (ERR_SYS_NOT_READY);
        break;
    case WSAEINVAL:
        return (ERR_EINVAL);
        break;
    case WSAVERNOTSUPPORTED:
        return (ERR_VER_NOT_SUPPORTED);
        break;
    }
    network_initialized = 1;
    return (0);
}

void deinit_winsock(void)
{
    network_initialized = 0;
    WSACleanup();
}


connection::connection (void)
{
	 the_socket = 0;
	 in_index = 0;
	 out_index = 0;
	 in_buffer_total = 0;
	 out_buffer_total = 0;
	 in_buffer = 0;

	 in_buffer = new char[SOCKET_BUFFER_SIZE];
	 out_buffer = new char[SOCKET_BUFFER_SIZE];
    
    last_winsock_error = 0;
}

connection::~connection (void)
{
    delete [] in_buffer;
    // NooN
    delete [] out_buffer;
    // NooN ^^
}

int gensock_is_a_number (char far* string)
{
    while (*string) 
    {
		  if (!isdigit (*string))
        {
            return (0);
        }
        string++;
    }
    return (1);
}

//
// 
-------------------------------------------------------------------------
--
//

int connection::get_connected (char FAR * hostname, char FAR * service)
{
    struct hostent FAR *  hostentry;
    struct servent FAR *  serventry;
    unsigned long     ip_address;
    struct sockaddr_in    sa_in;
    int           our_port;
    int           nott = 0;
    int           retval, err_code;
    unsigned long     ioctl_blocking = 1;
    char          message[512];
    
    // if the ctor couldn't get a buffer
    if (!in_buffer || !out_buffer)
        return (ERR_CANT_MALLOC);
    
    // --------------------------------------------------
    // resolve the service name
    //
    
    // If they've specified a number, just use it.
    if (gensock_is_a_number (service)) 
    {
        char far* tail;
        our_port = (int) strtol (service, &tail, 10);
        if (tail == service) 
        {
            return (ERR_CANT_RESOLVE_SERVICE);
        }
        else 
        {
            our_port = htons (our_port);
        }
    }
    else 
    {
        // we have a name, we must resolve it.
        serventry = getservbyname (service, (LPSTR)"tcp");
        
        if (serventry)
            our_port = serventry->s_port;
        else 
        {
            retval = WSAGetLastError();
            // Chicago beta is throwing a WSANO_RECOVERY here...
            if ((retval == WSANO_DATA) || (retval == WSANO_RECOVERY)) 
            {
                return (ERR_CANT_RESOLVE_SERVICE);
            }
            else 
            {
                return (retval - 5000);
            }
        }
    }
    
    // --------------------------------------------------
    // resolve the hostname/ipaddress
    //
    
    if ((ip_address = inet_addr (hostname)) != INADDR_NONE) 
    {
        sa_in.sin_addr.s_addr = ip_address;
    }
    else 
    {
        if ((hostentry = gethostbyname(hostname)) == NULL) 
        {
            return (ERR_CANT_RESOLVE_HOSTNAME);
        }
        sa_in.sin_addr.s_addr = *(long far *)hostentry->h_addr;
#if 0
        {
            OutputDebugString(inet_ntoa(sa_in.sin_addr));
        }
#endif
    }
    
    
    // --------------------------------------------------
    // get a socket
    //
    
    if ((the_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        return (ERR_CANT_GET_SOCKET);
    }
    
    sa_in.sin_family = AF_INET;
    sa_in.sin_port = our_port;
    
    // set socket options.  DONTLINGER will give us a more graceful 
disconnect
    
    // MDS yes, and also terminate our connections before the last 
command
    // has been completely sent causing abnormal terminations on the 
receiving
    // side! 
    // From www.lcg.org/sock-faq
    // "... SO_LINGER seems to be required to guarantee delivery of all 
data."
    //20000410  
#if 0  
    setsockopt(the_socket,SOL_SOCKET,SO_DONTLINGER,(char *) &nott, 
sizeof(nott));
#endif
    // get a connection
    
    if ((retval = connect (the_socket,
        (struct sockaddr *)&sa_in,
        sizeof(struct sockaddr_in))==SOCKET_ERROR)) 
    {
        switch ((err_code = WSAGetLastError())) 
        {
            // twiddle our thumbs until the connect succeeds 
        case WSAEWOULDBLOCK:
            break;
        case WSAECONNREFUSED:
            return (ERR_CONNECTION_REFUSED);
            break;
        default:
            wsprintf(message, "unexpected error %d from winsock\n", 
err_code);
            complain(message);
            return (ERR_CANT_CONNECT);
            break;
        }
    }
    
    owner_task = GET_CURRENT_TASK;
    
    // Make this a non-blocking socket
    ioctlsocket (the_socket, FIONBIO, &ioctl_blocking);
    
    // make the FD_SET and timeout structures for later operations...
    
    FD_ZERO (&fds);
    FD_SET  (the_socket, &fds);
    
    // normal timeout, can be changed by the wait option.
    timeout.tv_sec = 30;
    timeout.tv_usec = 0;
    
    return (0);
}


//
//-----------------------------------------------------------------------
----
//
// The 'wait' parameter, if set, says to return WAIT_A_BIT
// if there's no data waiting to be read.

int connection::get_buffer(int wait)
{
    int retval;
    int bytes_read = 0;
    unsigned long ready_to_read = 0;
    
    // Use select to see if data is waiting...
    
    FD_ZERO (&fds);
    FD_SET  (the_socket, &fds);
    
    // if wait is set, we are polling, return immediately
    if (wait) 
    {
        timeout.tv_sec = 0;
    }
    else 
    {
        timeout.tv_sec = 30;
    }
    
    if ((retval = select (0, &fds, NULL, NULL, &timeout))
        == SOCKET_ERROR) 
    {
        char what_error[256];
        int error_code = WSAGetLastError();
        
        if (error_code == WSAEINPROGRESS && wait) 
        {
            return (WAIT_A_BIT);
        }
        
        wsprintf (what_error,
            "connection::get_buffer() unexpected error from select: %d",
            error_code);
        complain (what_error);
    }
    
    // if we don't want to wait
    if (!retval && wait) 
    {
        return (WAIT_A_BIT);
    }
    
    // we have data waiting...
    bytes_read = recv (the_socket,in_buffer,SOCKET_BUFFER_SIZE,0);
    
    // just in case.
    if (bytes_read == 0) 
    {
        // connection terminated (semi-) gracefully by the other side
        return (ERR_NOT_CONNECTED);
    }
    
    if (bytes_read == SOCKET_ERROR) 
    {
        char what_error[256];
        int ws_error = WSAGetLastError();
        switch (ws_error) {
            // all these indicate loss of connection (are there more?)
        case WSAENOTCONN:
        case WSAENETDOWN:
        case WSAENETUNREACH:
        case WSAENETRESET:
        case WSAECONNABORTED:
        case WSAECONNRESET:
            return (ERR_NOT_CONNECTED);
            break;
            
        case WSAEWOULDBLOCK:
            return (WAIT_A_BIT);
            break;
            
        default:
            wsprintf (what_error,
                "connection::get_buffer() unexpected error: %d",
                ws_error);
            complain (what_error);
        }
    }
    
    // reset buffer indices.
    in_buffer_total = bytes_read;
    in_index = 0;
    return (0);
    
}

//
//-----------------------------------------------------------------------
----
// get a character from this connection.
//

int connection::getchar(int wait, char FAR * ch)
{
    int retval;
    
    if (in_index >= in_buffer_total) 
    {
        if ((retval = get_buffer(wait)))
            return (retval);
    }
    *ch = in_buffer[in_index++];
    return (0);
}


//
//-----------------------------------------------------------------------
----
// FIXME: should try to handle the fact that send can only take
// an int, not an unsigned long.

int connection::put_data (char far* data, unsigned long length)
{
    int num_sent;
    int retval;
    
    FD_ZERO (&fds);
    FD_SET  (the_socket, &fds);
    
    timeout.tv_sec = 30;
    
    while (length > 0) 
    {
        if ((retval = select (0, NULL, &fds, NULL, &timeout)) == 
SOCKET_ERROR) 
        {
            char what_error[256];
            int error_code = WSAGetLastError();
            
            wsprintf (what_error,
                "connection::put_data() unexpected error from select: 
%d",
                error_code);
            complain (what_error);
        }
        
        num_sent = send (the_socket,
            data,
            length > 1024 ? 1024 : (int)length,
            0);
        
        if (num_sent == SOCKET_ERROR) 
        {
            char what_error[256];
            int ws_error = WSAGetLastError();
            switch (ws_error) 
            {
                // this is the only error we really expect to see.
            case WSAENOTCONN:
                return (ERR_NOT_CONNECTED);
                break;
                
                // seems that we can still get a block
            case WSAEWOULDBLOCK:
            case WSAEINPROGRESS:
                break;
                
            default:
                wsprintf (what_error,
                    "connection::put_data() unexpected error from send(): 
%d",
                    ws_error);
                complain (what_error);
                return (ERR_SENDING_DATA);
            }
        }
        else 
        {
            length -= num_sent;
            data += num_sent;
        }
    }
    
    return (0);
}

//
//
// buffered output
//

int connection::put_data_buffered (char far* data, unsigned long length)
{
    unsigned int sorta_sent = 0;
    int retval;
    
    while (length) 
    {
        if ((out_index + length) < SOCKET_BUFFER_SIZE) 
        {
            // we won't overflow, simply copy into the buffer
            memcpy (out_buffer + out_index, data, (size_t) length);
            out_index += (unsigned int) length;
            length = 0;
        }
        else 
        {
            unsigned int orphaned_chunk = SOCKET_BUFFER_SIZE - out_index;
            // we will overflow, handle it
            memcpy (out_buffer + out_index, data, orphaned_chunk);
            // send this buffer...
            if ((retval = put_data (out_buffer, SOCKET_BUFFER_SIZE))) 
            {
                return (retval);
            }
            length -= orphaned_chunk;
            out_index = 0;
            data += orphaned_chunk;
        }
    }
    
    return (0);
}

int connection::put_data_flush (void)
{
    int retval;
    
    if ((retval = put_data (out_buffer, out_index)))
        return (retval);
    else
        out_index = 0;
    
    return(0);
}

//
//-----------------------------------------------------------------------
----
//

int connection::close (void)
{
    if (closesocket(the_socket) == SOCKET_ERROR)
        return (ERR_CLOSING);
    else
        return (0);
}


connection_list::connection_list (void)
{
    next = 0;
}

connection_list::~connection_list(void)
{
    delete data;
}

// add a new connection to the list

void connection_list::push (connection & conn)
{
    connection_list * new_conn;
    
    new_conn = new connection_list();
    
    new_conn->data = data;
    new_conn->next = next;
    
    data = &conn;
    next = new_conn;
    
}

int connection_list::how_many_are_mine(void)
{
    TASK_HANDLE_TYPE  current_task = GET_CURRENT_TASK;
    connection_list * iter = this;
    int num = 0;
    
    while (iter->data)
    {
        if (iter->data->get_owner_task() == current_task)
            num++;
        iter = iter->next;
    }
    return (num);
}

// find a particular socket's connection object.

connection * connection_list::find (SOCKET sock)
{
    connection_list * iter = this;
    
    while (iter->data) 
    {
        if (iter->data->get_socket() == sock)
            return (iter->data);
        iter = iter->next;
    }
    return (0);
}

void connection_list::remove (socktag sock)
{
    // at the end
    if (!data)
        return;
    
    // we can assume next is valid because
    // the last node is always {0,0}
    if (data == sock) 
    {
        delete data;
        data = next->data;
        next = next->next;  // 8^)
        return;
    }
    
    // recurse
    next->remove(sock);
}


//
// 
-------------------------------------------------------------------------
--
// global variables (shared by all DLL users)


//
//-----------------------------------------------------------------------
----
//


extern "C" 
{
    INT WINAPI DllMain (HANDLE hInst, ULONG reason_called,LPVOID 
reserved)
    {
        
        switch (reason_called) 
        {
        case DLL_PROCESS_ATTACH:
            // init 
            dll_module_handle = hInst;
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
            break;
            
        default:
            break;
        }
        return (1);
    }

// 
-------------------------------------------------------------------------
--
// C/DLL interface
//

int GENSOCK_EXPORT CELLBACK gensock_connect (char FAR * hostname,
                 char FAR * service,
                 socktag FAR * pst)
{
    int retval;
    connection * conn = new connection;
    
    if (!conn)
        return (ERR_INITIALIZING);
    
    // if this task hasn't opened any sockets yet, then
    // call WSAStartup()
    
    if (global_socket_list.how_many_are_mine() < 1)
        init_winsock();
    
    global_socket_list.push(*conn);
    
    if ((retval = conn->get_connected (hostname, service))) 
    {
        gensock_close(conn);
        *pst = 0;
        return (retval);
    }
    *pst = (void FAR *) conn;
    
    return (0);
}

//
//
//

int GENSOCK_EXPORT CELLBACK gensock_getchar (socktag st, int wait, char 
FAR * ch)
{
    connection * conn;
    int retval = 0;
    
    conn = (connection *) st;
    if (!conn)
        return (ERR_NOT_A_SOCKET);
    
    if ((retval = conn->getchar(wait, ch)))
        return (retval);
    else
        return (0);
}


//-----------------------------------------------------------------------
----
//
//

int GENSOCK_EXPORT CELLBACK 
gensock_put_data (socktag st, char FAR * data, unsigned long length)
{
    connection * conn;
    int retval = 0;
    
    conn = (connection *) st;
    
    if (!conn)
        return (ERR_NOT_A_SOCKET);
    
    if ((retval = conn->put_data(data, length)))
        return (retval);
    
    return (0);
}

//-----------------------------------------------------------------------
----
//
//

int GENSOCK_EXPORT CELLBACK gensock_put_data_buffered (socktag st, char 
FAR * data, unsigned long length)
{
    connection * conn;
    int retval = 0;
    
    conn = (connection *) st;
    
    if (!conn)
        return (ERR_NOT_A_SOCKET);
    
    if ((retval = conn->put_data_buffered (data, length)))
        return (retval);
    
    return (0);
}

//-----------------------------------------------------------------------
----
//
//

int GENSOCK_EXPORT CELLBACK gensock_put_data_flush (socktag st)
{
    connection * conn;
    int retval = 0;
    
    conn = (connection *) st;
    
    if (!conn)
        return (ERR_NOT_A_SOCKET);
    
    if ((retval = conn->put_data_flush() ))
        return (retval);
    
    return (0);
}

//-----------------------------------------------------------------------
----
//
//
int GENSOCK_EXPORT CELLBACK gensock_gethostname (char FAR * name, int 
namelen)
{
    int retval;
    if ((retval = gethostname(name, namelen))) 
    {
        return (retval - 5000);
    }
    else return (0);
}


int GENSOCK_EXPORT CELLBACK gensock_close (socktag st)
{
    connection * conn;
    int retval;
    
    conn = (connection *) st;
    
    if (!conn)
        return (ERR_NOT_A_SOCKET);
    
    if ((retval = conn->close()))
        return (retval);
    
    global_socket_list.remove((connection *)st);
    
    if (global_socket_list.how_many_are_mine() < 1) 
    {
        deinit_winsock();
    }
    
    return (0);
}

} // extern "C"


---------gwinsock.cpp------------

---------- gwinsock.h------------

and gwinsock.h

/* $Id: gensock.h 1.81 2004/12/25 22:06:11 NooN Exp $ */
/* $Id: gensock.h 1.8 1995/01/25 23:28:11 rushing Exp $ */
#define ERR_CANT_MALLOC             4001
#define ERR_SENDING_DATA            4002
#define ERR_INITIALIZING            4003
#define ERR_VER_NOT_SUPPORTED       4004
#define ERR_EINVAL                  4005
#define ERR_SYS_NOT_READY           4006
#define ERR_CANT_RESOLVE_HOSTNAME   4007
#define ERR_CANT_GET_SOCKET         4008
#define ERR_READING_SOCKET          4009
#define ERR_NOT_A_SOCKET            4010
#define ERR_BUSY                    4011
#define ERR_CLOSING                 4012
#define WAIT_A_BIT                  4013
#define ERR_CANT_RESOLVE_SERVICE    4014
#define ERR_CANT_CONNECT            4015
#define ERR_NOT_CONNECTED           4016
#define ERR_CONNECTION_REFUSED      4017

#define ERR_NO_ERROR_CODE           -5000
/* this is returned by misbehaving stacks that
 * fail, but don't set an error code
 */

typedef void * socktag;


     //	#ifdef __BORLANDC__
	   
        #ifdef __BC45__
        #define CELLBACK CALLBACK

		  #define GENSOCK_EXPORT __export
		#endif
	
 		#ifdef __BC55__

 		#define CELLBACK CALLBACK
                #define GENSOCK_EXPORT __export

		#endif

	#ifdef __BC600__
	#define CELLBACK CALLBACK

           		#define CELLBACK CALLBACK
                #define GENSOCK_EXPORT __export

        /*
		            #ifdef gwinsock_main
                            #define GENSOCK_EXPORT __declspec(dllexport)
					#else
                             #define GENSOCK_EXPORT __declspec(dllimport)
					#endif
   */
		#endif

 // #endif // borlandc


 #ifdef __DMC__

  #define CELLBACK

		#ifdef gwinsock_main
			#define GENSOCK_EXPORT __declspec(dllexport)
		#else
			#define GENSOCK_EXPORT __declspec(dllimport)
		#endif

	#endif



  #ifdef __WATCOM__
  
#define CELLBACK CALLBACK


		#ifdef gwinsock_main
			#define GENSOCK_EXPORT __declspec(dllexport)
		#else
			#define GENSOCK_EXPORT __declspec(dllimport)
		#endif

	#endif

 #ifdef __GCC__

  #define CELLBACK

		#ifdef gwinsock_main
			#define GENSOCK_EXPORT __declspec(dllexport)
		#else
			#define GENSOCK_EXPORT __declspec(dllimport)
		#endif

	#endif


#ifdef __MSVC__

#define CELLBACK CALLBACK

	#ifdef gwinsock_main
			#define GENSOCK_EXPORT __declspec(dllexport)
		#else
			#define GENSOCK_EXPORT __declspec(dllimport)
		#endif
  //#define GENSOCK_EXPORT FAR PASCAL

#endif

#ifdef __cplusplus
extern "C" {
#endif
/* function prototypes */

int GENSOCK_EXPORT CELLBACK gensock_connect    (char  * hostname,
                     char * service,
                     socktag * pst);

int GENSOCK_EXPORT CELLBACK gensock_getchar    (socktag st,
                     int wait,
							char * ch);

int GENSOCK_EXPORT CELLBACK gensock_put_data   (socktag st,
                     char * data,
                     unsigned long length);

int GENSOCK_EXPORT CELLBACK gensock_close  (socktag st);

int GENSOCK_EXPORT CELLBACK gensock_gethostname    (char * name, int 
namelen);

int GENSOCK_EXPORT CELLBACK gensock_put_data_buffered (socktag st,
                          char * data,
                          unsigned long length);

int GENSOCK_EXPORT CELLBACK gensock_put_data_flush (socktag st);

#ifdef __cplusplus
}
#endif

------------------- gwinsock.h -------------


Can someone help this?



Janne Naukkarinen
kiviapaja hotmail.com
Jan 14 2004
parent "Walter" <walter digitalmars.com> writes:
EXETYPE WINDOWS

specifies a 16 bit output. Use

EXETYPE NT

instead. See www.digitalmars.com/ctg/ctgDefFiles.html


"Janne Naukkarinen" <kiviapaja hotmail.com> wrote in message
news:bu4bkg$299g$1 digitaldaemon.com...
 This is 32-bit DLL compiling.


  From kiviapaja hotmail.com

 Why next example fails?

 dmc -mn -WD ../gwinsock.cpp -w -D__DMC__ -Dgwinsock_main  kernel32.lib
 user32.lib gdi32.lib comdlg32.lib wsock32.lib > err2.txt


 link gwinsock,,,kernel32+user32+gdi32+comdlg32+wsock32,gwinsock/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

 OPTLINK : Warning 148: USE16/USE32 Mismatch : DGROUP
 F:\DM\BIN\..\lib\SNN.lib(dllstart)
  Error 83: Illegal frame on start address
 OPTLINK : Warning 174: 32-bit Segments Inappropriate for 16-bit Segmented
 output
 gwinsock.obj(gwinsock)
  Error 116: NEAR call to IMPORT at Relative 00025H  from
  Segment _TEXT
  FRAME  = Frame of Group FLAT 0000
  TARGET = External Symbol _WSAStartup 8 00000H
  FIXUPP Type = 32-bit Conditional JMP

 --- errorlevel 2

 Is this from source code or .def

 My def is like this:

 LIBRARY gwinsock
 DESCRIPTION 'GWinSock -- socket wrapper dll'
 EXETYPE WINDOWS
 EXPORTS
 _gensock_close  1
 _gensock_connect  2
 _gensock_getchar  3
 _gensock_gethostname  4
 _gensock_put_data  5
 _gensock_put_data_buffered  6
 _gensock_put_data_flush  7


 My source is like this

 ------- gwinsock.cpp ------------


 // -*- C++ -*-
 // generic socket DLL, winsock version
 // disclaimer:  a C programmer wrote this.

 // $Id: gensock.cpp 1.151 2004/12/25 22:07:10 NooN Exp $
 // $Id: gensock.cpp 1.15 1994/11/23 22:38:10 rushing Exp $

 #include <windows.h>

 #include <string.h>
 #include <ctype.h>

 extern "C"
 {
 #include <winsock.h>
 #include "gwinsock.h"
 }


 #ifdef _DEBUG
 #ifndef __BORLANDC__
   #define _CRTDBG_MAP_ALLOC
 #include <stdlib.h>
 #include <crtdbg.h>
 #else
 #include <stdlib.h>
 #endif
 #else
   #include <stdlib.h>
 #endif



 //MDS increased buffer from 512 19991214
 #define SOCKET_BUFFER_SIZE  1500

 // This is for NT
 HANDLE  dll_module_handle;
 #define GET_CURRENT_TASK    dll_module_handle
 #define TASK_HANDLE_TYPE    HANDLE




 //
 //
 -------------------------------------------------------------------------
 --
 // container for a buffered SOCK_STREAM.

 class connection
 {
 private:
     SOCKET          the_socket;
 char *          in_buffer;
     char *          out_buffer;
     unsigned int    in_index;
 unsigned int    out_index;
 unsigned int    in_buffer_total;
 unsigned int    out_buffer_total;
 unsigned int    last_winsock_error;
 TASK_HANDLE_TYPE owner_task;
 fd_set          fds;
 struct timeval  timeout;

 public:

 connection (void);
 ~connection (void);

 int       get_connected (char far * hostname, char far *
 service);
 SOCKET    get_socket(void) { return (the_socket); }
 TASK_HANDLE_TYPE get_owner_task(void) { return (owner_task); }
 int       get_buffer(int wait);
 int       close (void);
 int       getchar (int wait, char far * ch);
 int       put_data (char far * data, unsigned long length);
 int       put_data_buffered (char far* data, unsigned long
 length);
 int       put_data_flush (void);
 };

 //
 //-----------------------------------------------------------------------
 ----
 // we keep lists of connections in this class

 class connection_list
 {
 private:
     connection *        data;
     connection_list *   next;

 public:
     connection_list   (void);
     ~connection_list  (void);
     void push         (connection & conn);

     // should really use pointer-to-memberfun for these
     connection * find (SOCKET sock);
     int how_many_are_mine (void);

     void remove       (socktag sock);
 };




 connection_list global_socket_list;
 int network_initialized;


 //int  init_winsock (void);
 //void deinit_winsock (void);

 //
 //
 //


 #ifdef _DEBUG
 void complain (char * message)
 {
     OutputDebugString (message);
 }
 #else
 void complain (char * message)
 {
     MessageBox (NULL, message, "GWINSOCK.DLL Error", MB_OK|MB_ICONHAND);
 }
 #endif


 //-----------------------------------------------------------------------
 ----
 //
 //

 int init_winsock(void)
 {
     int retval;
     WSADATA winsock_data;
     WORD version_required = 0x0101; // Version 1.1

     retval = WSAStartup (version_required, &winsock_data);

     switch (retval)
     {
     case 0:
         // successful
         break;
     case WSASYSNOTREADY:
         return (ERR_SYS_NOT_READY);
         break;
     case WSAEINVAL:
         return (ERR_EINVAL);
         break;
     case WSAVERNOTSUPPORTED:
         return (ERR_VER_NOT_SUPPORTED);
         break;
     }
     network_initialized = 1;
     return (0);
 }

 void deinit_winsock(void)
 {
     network_initialized = 0;
     WSACleanup();
 }


 connection::connection (void)
 {
 the_socket = 0;
 in_index = 0;
 out_index = 0;
 in_buffer_total = 0;
 out_buffer_total = 0;
 in_buffer = 0;

 in_buffer = new char[SOCKET_BUFFER_SIZE];
 out_buffer = new char[SOCKET_BUFFER_SIZE];

     last_winsock_error = 0;
 }

 connection::~connection (void)
 {
     delete [] in_buffer;
     // NooN
     delete [] out_buffer;
     // NooN ^^
 }

 int gensock_is_a_number (char far* string)
 {
     while (*string)
     {
   if (!isdigit (*string))
         {
             return (0);
         }
         string++;
     }
     return (1);
 }

 //
 //
 -------------------------------------------------------------------------
 --
 //

 int connection::get_connected (char FAR * hostname, char FAR * service)
 {
     struct hostent FAR *  hostentry;
     struct servent FAR *  serventry;
     unsigned long     ip_address;
     struct sockaddr_in    sa_in;
     int           our_port;
     int           nott = 0;
     int           retval, err_code;
     unsigned long     ioctl_blocking = 1;
     char          message[512];

     // if the ctor couldn't get a buffer
     if (!in_buffer || !out_buffer)
         return (ERR_CANT_MALLOC);

     // --------------------------------------------------
     // resolve the service name
     //

     // If they've specified a number, just use it.
     if (gensock_is_a_number (service))
     {
         char far* tail;
         our_port = (int) strtol (service, &tail, 10);
         if (tail == service)
         {
             return (ERR_CANT_RESOLVE_SERVICE);
         }
         else
         {
             our_port = htons (our_port);
         }
     }
     else
     {
         // we have a name, we must resolve it.
         serventry = getservbyname (service, (LPSTR)"tcp");

         if (serventry)
             our_port = serventry->s_port;
         else
         {
             retval = WSAGetLastError();
             // Chicago beta is throwing a WSANO_RECOVERY here...
             if ((retval == WSANO_DATA) || (retval == WSANO_RECOVERY))
             {
                 return (ERR_CANT_RESOLVE_SERVICE);
             }
             else
             {
                 return (retval - 5000);
             }
         }
     }

     // --------------------------------------------------
     // resolve the hostname/ipaddress
     //

     if ((ip_address = inet_addr (hostname)) != INADDR_NONE)
     {
         sa_in.sin_addr.s_addr = ip_address;
     }
     else
     {
         if ((hostentry = gethostbyname(hostname)) == NULL)
         {
             return (ERR_CANT_RESOLVE_HOSTNAME);
         }
         sa_in.sin_addr.s_addr = *(long far *)hostentry->h_addr;
 #if 0
         {
             OutputDebugString(inet_ntoa(sa_in.sin_addr));
         }
 #endif
     }


     // --------------------------------------------------
     // get a socket
     //

     if ((the_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
     {
         return (ERR_CANT_GET_SOCKET);
     }

     sa_in.sin_family = AF_INET;
     sa_in.sin_port = our_port;

     // set socket options.  DONTLINGER will give us a more graceful
 disconnect

     // MDS yes, and also terminate our connections before the last
 command
     // has been completely sent causing abnormal terminations on the
 receiving
     // side!
     // From www.lcg.org/sock-faq
     // "... SO_LINGER seems to be required to guarantee delivery of all
 data."
     //20000410
 #if 0
     setsockopt(the_socket,SOL_SOCKET,SO_DONTLINGER,(char *) &nott,
 sizeof(nott));
 #endif
     // get a connection

     if ((retval = connect (the_socket,
         (struct sockaddr *)&sa_in,
         sizeof(struct sockaddr_in))==SOCKET_ERROR))
     {
         switch ((err_code = WSAGetLastError()))
         {
             // twiddle our thumbs until the connect succeeds
         case WSAEWOULDBLOCK:
             break;
         case WSAECONNREFUSED:
             return (ERR_CONNECTION_REFUSED);
             break;
         default:
             wsprintf(message, "unexpected error %d from winsock\n",
 err_code);
             complain(message);
             return (ERR_CANT_CONNECT);
             break;
         }
     }

     owner_task = GET_CURRENT_TASK;

     // Make this a non-blocking socket
     ioctlsocket (the_socket, FIONBIO, &ioctl_blocking);

     // make the FD_SET and timeout structures for later operations...

     FD_ZERO (&fds);
     FD_SET  (the_socket, &fds);

     // normal timeout, can be changed by the wait option.
     timeout.tv_sec = 30;
     timeout.tv_usec = 0;

     return (0);
 }


 //
 //-----------------------------------------------------------------------
 ----
 //
 // The 'wait' parameter, if set, says to return WAIT_A_BIT
 // if there's no data waiting to be read.

 int connection::get_buffer(int wait)
 {
     int retval;
     int bytes_read = 0;
     unsigned long ready_to_read = 0;

     // Use select to see if data is waiting...

     FD_ZERO (&fds);
     FD_SET  (the_socket, &fds);

     // if wait is set, we are polling, return immediately
     if (wait)
     {
         timeout.tv_sec = 0;
     }
     else
     {
         timeout.tv_sec = 30;
     }

     if ((retval = select (0, &fds, NULL, NULL, &timeout))
         == SOCKET_ERROR)
     {
         char what_error[256];
         int error_code = WSAGetLastError();

         if (error_code == WSAEINPROGRESS && wait)
         {
             return (WAIT_A_BIT);
         }

         wsprintf (what_error,
             "connection::get_buffer() unexpected error from select: %d",
             error_code);
         complain (what_error);
     }

     // if we don't want to wait
     if (!retval && wait)
     {
         return (WAIT_A_BIT);
     }

     // we have data waiting...
     bytes_read = recv (the_socket,in_buffer,SOCKET_BUFFER_SIZE,0);

     // just in case.
     if (bytes_read == 0)
     {
         // connection terminated (semi-) gracefully by the other side
         return (ERR_NOT_CONNECTED);
     }

     if (bytes_read == SOCKET_ERROR)
     {
         char what_error[256];
         int ws_error = WSAGetLastError();
         switch (ws_error) {
             // all these indicate loss of connection (are there more?)
         case WSAENOTCONN:
         case WSAENETDOWN:
         case WSAENETUNREACH:
         case WSAENETRESET:
         case WSAECONNABORTED:
         case WSAECONNRESET:
             return (ERR_NOT_CONNECTED);
             break;

         case WSAEWOULDBLOCK:
             return (WAIT_A_BIT);
             break;

         default:
             wsprintf (what_error,
                 "connection::get_buffer() unexpected error: %d",
                 ws_error);
             complain (what_error);
         }
     }

     // reset buffer indices.
     in_buffer_total = bytes_read;
     in_index = 0;
     return (0);

 }

 //
 //-----------------------------------------------------------------------
 ----
 // get a character from this connection.
 //

 int connection::getchar(int wait, char FAR * ch)
 {
     int retval;

     if (in_index >= in_buffer_total)
     {
         if ((retval = get_buffer(wait)))
             return (retval);
     }
     *ch = in_buffer[in_index++];
     return (0);
 }


 //
 //-----------------------------------------------------------------------
 ----
 // FIXME: should try to handle the fact that send can only take
 // an int, not an unsigned long.

 int connection::put_data (char far* data, unsigned long length)
 {
     int num_sent;
     int retval;

     FD_ZERO (&fds);
     FD_SET  (the_socket, &fds);

     timeout.tv_sec = 30;

     while (length > 0)
     {
         if ((retval = select (0, NULL, &fds, NULL, &timeout)) ==
 SOCKET_ERROR)
         {
             char what_error[256];
             int error_code = WSAGetLastError();

             wsprintf (what_error,
                 "connection::put_data() unexpected error from select:
 %d",
                 error_code);
             complain (what_error);
         }

         num_sent = send (the_socket,
             data,
             length > 1024 ? 1024 : (int)length,
             0);

         if (num_sent == SOCKET_ERROR)
         {
             char what_error[256];
             int ws_error = WSAGetLastError();
             switch (ws_error)
             {
                 // this is the only error we really expect to see.
             case WSAENOTCONN:
                 return (ERR_NOT_CONNECTED);
                 break;

                 // seems that we can still get a block
             case WSAEWOULDBLOCK:
             case WSAEINPROGRESS:
                 break;

             default:
                 wsprintf (what_error,
                     "connection::put_data() unexpected error from send():
 %d",
                     ws_error);
                 complain (what_error);
                 return (ERR_SENDING_DATA);
             }
         }
         else
         {
             length -= num_sent;
             data += num_sent;
         }
     }

     return (0);
 }

 //
 //
 // buffered output
 //

 int connection::put_data_buffered (char far* data, unsigned long length)
 {
     unsigned int sorta_sent = 0;
     int retval;

     while (length)
     {
         if ((out_index + length) < SOCKET_BUFFER_SIZE)
         {
             // we won't overflow, simply copy into the buffer
             memcpy (out_buffer + out_index, data, (size_t) length);
             out_index += (unsigned int) length;
             length = 0;
         }
         else
         {
             unsigned int orphaned_chunk = SOCKET_BUFFER_SIZE - out_index;
             // we will overflow, handle it
             memcpy (out_buffer + out_index, data, orphaned_chunk);
             // send this buffer...
             if ((retval = put_data (out_buffer, SOCKET_BUFFER_SIZE)))
             {
                 return (retval);
             }
             length -= orphaned_chunk;
             out_index = 0;
             data += orphaned_chunk;
         }
     }

     return (0);
 }

 int connection::put_data_flush (void)
 {
     int retval;

     if ((retval = put_data (out_buffer, out_index)))
         return (retval);
     else
         out_index = 0;

     return(0);
 }

 //
 //-----------------------------------------------------------------------
 ----
 //

 int connection::close (void)
 {
     if (closesocket(the_socket) == SOCKET_ERROR)
         return (ERR_CLOSING);
     else
         return (0);
 }


 connection_list::connection_list (void)
 {
     next = 0;
 }

 connection_list::~connection_list(void)
 {
     delete data;
 }

 // add a new connection to the list

 void connection_list::push (connection & conn)
 {
     connection_list * new_conn;

     new_conn = new connection_list();

     new_conn->data = data;
     new_conn->next = next;

     data = &conn;
     next = new_conn;

 }

 int connection_list::how_many_are_mine(void)
 {
     TASK_HANDLE_TYPE  current_task = GET_CURRENT_TASK;
     connection_list * iter = this;
     int num = 0;

     while (iter->data)
     {
         if (iter->data->get_owner_task() == current_task)
             num++;
         iter = iter->next;
     }
     return (num);
 }

 // find a particular socket's connection object.

 connection * connection_list::find (SOCKET sock)
 {
     connection_list * iter = this;

     while (iter->data)
     {
         if (iter->data->get_socket() == sock)
             return (iter->data);
         iter = iter->next;
     }
     return (0);
 }

 void connection_list::remove (socktag sock)
 {
     // at the end
     if (!data)
         return;

     // we can assume next is valid because
     // the last node is always {0,0}
     if (data == sock)
     {
         delete data;
         data = next->data;
         next = next->next;  // 8^)
         return;
     }

     // recurse
     next->remove(sock);
 }


 //
 //
 -------------------------------------------------------------------------
 --
 // global variables (shared by all DLL users)


 //
 //-----------------------------------------------------------------------
 ----
 //


 extern "C"
 {
     INT WINAPI DllMain (HANDLE hInst, ULONG reason_called,LPVOID
 reserved)
     {

         switch (reason_called)
         {
         case DLL_PROCESS_ATTACH:
             // init
             dll_module_handle = hInst;
             break;
         case DLL_THREAD_ATTACH:
             break;
         case DLL_THREAD_DETACH:
             break;
         case DLL_PROCESS_DETACH:
             break;

         default:
             break;
         }
         return (1);
     }

 //
 -------------------------------------------------------------------------
 --
 // C/DLL interface
 //

 int GENSOCK_EXPORT CELLBACK gensock_connect (char FAR * hostname,
                  char FAR * service,
                  socktag FAR * pst)
 {
     int retval;
     connection * conn = new connection;

     if (!conn)
         return (ERR_INITIALIZING);

     // if this task hasn't opened any sockets yet, then
     // call WSAStartup()

     if (global_socket_list.how_many_are_mine() < 1)
         init_winsock();

     global_socket_list.push(*conn);

     if ((retval = conn->get_connected (hostname, service)))
     {
         gensock_close(conn);
         *pst = 0;
         return (retval);
     }
     *pst = (void FAR *) conn;

     return (0);
 }

 //
 //
 //

 int GENSOCK_EXPORT CELLBACK gensock_getchar (socktag st, int wait, char
 FAR * ch)
 {
     connection * conn;
     int retval = 0;

     conn = (connection *) st;
     if (!conn)
         return (ERR_NOT_A_SOCKET);

     if ((retval = conn->getchar(wait, ch)))
         return (retval);
     else
         return (0);
 }


 //-----------------------------------------------------------------------
 ----
 //
 //

 int GENSOCK_EXPORT CELLBACK
 gensock_put_data (socktag st, char FAR * data, unsigned long length)
 {
     connection * conn;
     int retval = 0;

     conn = (connection *) st;

     if (!conn)
         return (ERR_NOT_A_SOCKET);

     if ((retval = conn->put_data(data, length)))
         return (retval);

     return (0);
 }

 //-----------------------------------------------------------------------
 ----
 //
 //

 int GENSOCK_EXPORT CELLBACK gensock_put_data_buffered (socktag st, char
 FAR * data, unsigned long length)
 {
     connection * conn;
     int retval = 0;

     conn = (connection *) st;

     if (!conn)
         return (ERR_NOT_A_SOCKET);

     if ((retval = conn->put_data_buffered (data, length)))
         return (retval);

     return (0);
 }

 //-----------------------------------------------------------------------
 ----
 //
 //

 int GENSOCK_EXPORT CELLBACK gensock_put_data_flush (socktag st)
 {
     connection * conn;
     int retval = 0;

     conn = (connection *) st;

     if (!conn)
         return (ERR_NOT_A_SOCKET);

     if ((retval = conn->put_data_flush() ))
         return (retval);

     return (0);
 }

 //-----------------------------------------------------------------------
 ----
 //
 //
 int GENSOCK_EXPORT CELLBACK gensock_gethostname (char FAR * name, int
 namelen)
 {
     int retval;
     if ((retval = gethostname(name, namelen)))
     {
         return (retval - 5000);
     }
     else return (0);
 }


 int GENSOCK_EXPORT CELLBACK gensock_close (socktag st)
 {
     connection * conn;
     int retval;

     conn = (connection *) st;

     if (!conn)
         return (ERR_NOT_A_SOCKET);

     if ((retval = conn->close()))
         return (retval);

     global_socket_list.remove((connection *)st);

     if (global_socket_list.how_many_are_mine() < 1)
     {
         deinit_winsock();
     }

     return (0);
 }

 } // extern "C"


 ---------gwinsock.cpp------------

 ---------- gwinsock.h------------

 and gwinsock.h

 /* $Id: gensock.h 1.81 2004/12/25 22:06:11 NooN Exp $ */
 /* $Id: gensock.h 1.8 1995/01/25 23:28:11 rushing Exp $ */
 #define ERR_CANT_MALLOC             4001
 #define ERR_SENDING_DATA            4002
 #define ERR_INITIALIZING            4003
 #define ERR_VER_NOT_SUPPORTED       4004
 #define ERR_EINVAL                  4005
 #define ERR_SYS_NOT_READY           4006
 #define ERR_CANT_RESOLVE_HOSTNAME   4007
 #define ERR_CANT_GET_SOCKET         4008
 #define ERR_READING_SOCKET          4009
 #define ERR_NOT_A_SOCKET            4010
 #define ERR_BUSY                    4011
 #define ERR_CLOSING                 4012
 #define WAIT_A_BIT                  4013
 #define ERR_CANT_RESOLVE_SERVICE    4014
 #define ERR_CANT_CONNECT            4015
 #define ERR_NOT_CONNECTED           4016
 #define ERR_CONNECTION_REFUSED      4017

 #define ERR_NO_ERROR_CODE           -5000
 /* this is returned by misbehaving stacks that
  * fail, but don't set an error code
  */

 typedef void * socktag;


      // #ifdef __BORLANDC__

         #ifdef __BC45__
         #define CELLBACK CALLBACK

   #define GENSOCK_EXPORT __export
 #endif

   #ifdef __BC55__

   #define CELLBACK CALLBACK
                 #define GENSOCK_EXPORT __export

 #endif

 #ifdef __BC600__
 #define CELLBACK CALLBACK

            #define CELLBACK CALLBACK
                 #define GENSOCK_EXPORT __export

         /*
             #ifdef gwinsock_main
                             #define GENSOCK_EXPORT __declspec(dllexport)
 #else
                              #define GENSOCK_EXPORT __declspec(dllimport)
 #endif
    */
 #endif

  // #endif // borlandc


  #ifdef __DMC__

   #define CELLBACK

 #ifdef gwinsock_main
 #define GENSOCK_EXPORT __declspec(dllexport)
 #else
 #define GENSOCK_EXPORT __declspec(dllimport)
 #endif

 #endif



   #ifdef __WATCOM__

 #define CELLBACK CALLBACK


 #ifdef gwinsock_main
 #define GENSOCK_EXPORT __declspec(dllexport)
 #else
 #define GENSOCK_EXPORT __declspec(dllimport)
 #endif

 #endif

  #ifdef __GCC__

   #define CELLBACK

 #ifdef gwinsock_main
 #define GENSOCK_EXPORT __declspec(dllexport)
 #else
 #define GENSOCK_EXPORT __declspec(dllimport)
 #endif

 #endif


 #ifdef __MSVC__

 #define CELLBACK CALLBACK

 #ifdef gwinsock_main
 #define GENSOCK_EXPORT __declspec(dllexport)
 #else
 #define GENSOCK_EXPORT __declspec(dllimport)
 #endif
   //#define GENSOCK_EXPORT FAR PASCAL

 #endif

 #ifdef __cplusplus
 extern "C" {
 #endif
 /* function prototypes */

 int GENSOCK_EXPORT CELLBACK gensock_connect    (char  * hostname,
                      char * service,
                      socktag * pst);

 int GENSOCK_EXPORT CELLBACK gensock_getchar    (socktag st,
                      int wait,
 char * ch);

 int GENSOCK_EXPORT CELLBACK gensock_put_data   (socktag st,
                      char * data,
                      unsigned long length);

 int GENSOCK_EXPORT CELLBACK gensock_close  (socktag st);

 int GENSOCK_EXPORT CELLBACK gensock_gethostname    (char * name, int
 namelen);

 int GENSOCK_EXPORT CELLBACK gensock_put_data_buffered (socktag st,
                           char * data,
                           unsigned long length);

 int GENSOCK_EXPORT CELLBACK gensock_put_data_flush (socktag st);

 #ifdef __cplusplus
 }
 #endif

 ------------------- gwinsock.h -------------


 Can someone help this?



 Janne Naukkarinen
 kiviapaja hotmail.com
Jan 18 2004