22 November 2010

To align or not to align, that is the question!


All of the gSOAP runtime is compiled with member alignment (and needs to be for various reasons), so if you have code you are integrating with that contains structures that need to be compiled with /nomember_alignment, you will have to be a little careful about how you mix and match; however, aligned and unaligned structures can happily co-exist, if you do things right. What I typically do in this circumstance is to use the following #pragma directives:

#pragma member_alignment save
#pragma nomember_alignment
/* unsligned.h contains structures that need /nomember_alignment (or you could just include the actual structure definitions within
   The #pragma directives */
#include "unaligned.h"    
#pragma member_alignment restore

Please ensure  that generated gSOAP stubs and code that includes gSOAP header files is compiled with member alignment. Note that you can use the #pragma statements to include in your code structures that are not aligned.
The following brief example might help to illustrate how to adjust for aligned and unaligned structures being mixed in the same program module.
___________________________________
#ifndef __UNALIGNED_H__
#define __UNALIGNED_H__

typedef struct
{
   double a;
   double b;
   char str[60];
}
unaligned_i_struct_t;

typedef struct
{
   double result;
   char str[60];
}
unaligned_o_struct_t;

#ifdef __cplusplus
    extern "C" {
#endif

extern int unaligned_cstruct(unaligned_i_struct_t *, unaligned_o_struct_t *);

#ifdef __cplusplus
    }
#endif
#endif

_____________________________________________________
#include       /* toupper() */
#include
#include "unaligned.h"


int unaligned_cstruct(unaligned_i_struct_t *ibuf, unaligned_o_struct_t *obuf)
{
   char *tmp;

   obuf->result = ibuf->a * ibuf->b;
   strcpy(obuf->str, ibuf->str);
   tmp = obuf->str;
   while (*tmp)
   {
      *tmp = toupper(*tmp);
      tmp++;
   }
   return (1);
}
______________________________________

#include "soapH.h"
#include "cstruct.nsmap"

/* Change value of PORT to your assigned port number */
#define PORT 9191

int main(int argc, char **argv)
{
   int m, s;             /* master and slave sockets */
   struct soap soap;

   soap_init(&soap);

   m = soap_bind(&soap, NULL, PORT, 100);
   if (m < 0)
   {
      soap_print_fault(&soap, stderr);
      exit(-1);
   }

   fprintf(stderr, "Connection successful: master socket = %d\n", m);

   while (1)
   {
      s = soap_accept(&soap);
      fprintf(stderr, "Connection successful: slave socket = %d\n", s);
      if (s < 0)
      {
         soap_print_fault(&soap, stderr);
         exit(-1);
      }
      soap_serve(&soap);
      soap_end(&soap);
   }

   return 0;
}

____________________________________________
//gsoap ns service name:        cstruct
//gsoap ns service style:       rpc
//gsoap ns service encoding:    encoded
//gsoap ns service location:    http://www.somewhere.com:9191/cstruct.exe
//gsoap ns schema namespace:    urn:cstruct

struct i_struct
{
   double a;
   double b;
   char *str;
};

struct o_struct
{
   double result;
   char *str;
};

int ns__cstruct(struct i_struct *ibuf, struct o_struct *obuf);
____________________________________
#include "soapH.h"
#include       /* toupper() */

#pragma member_alignment save
#pragma nomember_alignment
#include "unaligned.h"
#pragma member_alignment restore

int ns__cstruct(struct soap *soap, struct i_struct *ibuf,
                                   struct o_struct *obuf)
{

    unaligned_i_struct_t unaligned_ibuf;
    unaligned_o_struct_t unaligned_obuf;

    unaligned_ibuf.a = ibuf->a;
    unaligned_ibuf.b = ibuf->b;
    strcpy(unaligned_ibuf.str, ibuf->str);

    unaligned_cstruct(&unaligned_ibuf, &unaligned_obuf);

    obuf->result = unaligned_obuf.result;
    obuf->str = soap_strdup(soap, unaligned_obuf.str);

       return (SOAP_OK);
}

_______________________________
$! build.com
$ cc:=cc   ! ensure that CC is really CC and not some symbol
$ lin*k:=  ! ensure the LINK command is just that
$!
$ soapcpp2 :== $gsoap$root:[bin]soapcpp2.exe
$
$ soapcpp2 "-c" cstruct.h
$ cc/names=(as_is,shortened)/prefix=all/float=ieee/ieee=denorm -
/warning=(disable=EMPTYSTRUCT) -
/include=gsoap$root:[include] cstruct.c
$
$ cc/names=(as_is,shortened)/prefix=all/float=ieee/ieee=denorm -
/warning=(disable=EMPTYSTRUCT) -
/extern=common/share_global/nomember_alignment -
/include=gsoap$root:[include] unaligned.c
$
$ cc/names=(as_is,shortened)/prefix=all/float=ieee/ieee=denorm -
/warning=(disable=EMPTYSTRUCT) -
/include=gsoap$root:[include] main.c
$ cc/names=(as_is,shortened)/prefix=all/float=ieee/ieee=denorm -
/warning=(disable=EMPTYSTRUCT) -
/include=gsoap$root:[include] soapc.c
$ cc/names=(as_is,shortened)/prefix=all/float=ieee/ieee=denorm -
/warning=(disable=EMPTYSTRUCT) -
/include=gsoap$root:[include] soapserver.c
$
$ link/exe=cstruct.exe main,cstruct,unaligned,soapc,soapserver,sys$input/opt
gsoap$root:[lib]gsoap.olb/lib
$

19 November 2010

gSOAP on OpenVMS V0.9 Released

BC&JA are happy to announce that V09 of gSOAP on OpenVMS is now available for download.
You may wish to peruse the release notes prior to requesting a kit by sending an email to brett.r.cameron(AT)gmail.com and johndapps(AT)gmail.com stating platform and OpenVMS version.

If you are an ACMS user, you might want to glance through the gSOAP FIDDLE User Guide, an utility which translates STDL into WSDL, thus automating the process of exposing ACMS Tasks as Web Services.

We are always happy to hear from people using the software and do try to listen to what you all have to say and recommend!

NOTE: please ensure that any DCL symbols for compilers and linkers are deleted prior to building gSOAP applications!

No Widget