You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@axis.apache.org by Mark Whitlock <ma...@uk.ibm.com> on 2004/12/09 16:43:22 UTC

Generating C stubs




Hi,
I'm investigating how to generate the C client stubs. There are two
approaches....
- Change WSDL2Ws so that it generates C stubs to the new dynamic C client
API.
- Generate the C stubs as a thin layer on top of the C++ stubs. This could
be done using the logic from the C binding generator tool that I'm
currently developing, driven from WSDL2Ws.

Paul Fremantle suggested the second approach and I'm weighing up the two
alternatives. Most fixes to WSDL2Ws need to be copied to 4 places: C
rpcenc, C doclit, C++ rpcenc and C++ doclit which is error prone. The
advantage to the generated C stubs calling the generated C++ stubs is that
it removed this duplication in WSDL2Ws. Here are some thoughts on generated
C stubs calling the generated C++ stubs, instead of the dynamic C API....

- Client applications that use generated stubs can also use the dynamic
client API. Generated stubs inherit methods that allow getting and setting
of headerblocks, attributes, etc. If generated C stubs call the generated
C++ stubs, C applications would have to link with the dynamic C++ API as
well as the dynamic C API. This is ok as long as C++ object instances are
mapped to C handles in the same way in the generated C stubs as in the
dynamic C API.

- Complex types are represented by classes in C++ but by structs in C. If
the underlying generated C++ stub (de)serializes classes and the generated
C stub casts these classes to structs, it relies on these generated classes
and structs having the same length and field offsets for all compilers on
all platforms. I tried this on Windows using MS Visual C++ and they were
the same length. Can we rely on this? The alternative approach of generated
C stubs calling the dynamic C API does not rely on this.

- Arrays are represented as structs in C and classes in C++ as these also
contain the array's length. The C++ implementation should have other useful
methods that overload operator[ ] and delete the array storage in the
destructor. For C++, a better implementation might be to use a template so
avoiding duplicated code for arrays of different types. Now the C and C++
representations really would be different and a C stub could not rely on a
C++ stub to generate such an array for use in C.

- Generated stubs (C++ stubs and the old C stubs) do not deallocate storage
for output or return parameters. It is up to the application to free/delete
the storage when appropriate. Storage for output complex objects is
allocated in a callback function AXIS_OBJECT_CREATE_FUNCT. So WSDL2Ws
generates an implementation of AXIS_OBJECT_CREATE_FUNCT which the client
engine calls when it needs to allocate storage for an output complex
object. If the generated C stubs call the generated C++ stubs, it will be
the generated C++ callback which allocates storage using new (not malloc).
Later on the C application will have to attempt to free this storage using
free(). Instead the generated C stubs would have to generate their own
callbacks which use malloc/free and then pass them into the generated C++
stubs using an extra private API.

- There are some places where generated C++ stubs allocate storage using
new, for instance in allocating an output array of primitives. Instead the
generated C++ stubs would have to be aware that they were being called from
a generated C stub and use malloc instead.

- I haven't investigated how this would work for C services. Following same
model, the Axis server would call a generated C++ skeleton which would call
a generated C skeleton which would call the application code. I am not
sufficiently familiar with the server to know if this would work.

- C applications would have to be compiled with a C++ compiler if their
generated C stubs called generated C++ stubs.

Generated C stubs calling generated C++ stubs is the best approach if...
- Users don't mind compiling their C code with a C++ compiler
- Classes and their corresponding structs are always the same length for
every compiler on every platform
- The tool that generates the C stubs is decoupled from WSDL2Ws (although
called by it), so that it doesn't break every time changes are made to
WSDL2Ws
- The generated C++ artifacts can be encapsulated within the generated C
artifacts so avoiding any confusion
- The server's generated C skeletons can be made to work in a similar way

Generated C stubs calling the dynamic C API is the best approach if...
- WSDL2Ws could be refactored so every change does not have to be made to
the C and C++ support separately

Comments?
Mark
Mark Whitlock
IBM


Re: Generating C stubs

Posted by Samisa Abeysinghe <sa...@gmail.com>.
Users may wish to have only C code, when it comes to C support. Hence,
we may have to generate structs for complex types in C code etc.

This sounds to me as if we would have to skip C++ and expose as much
as possible as C.

However, I would like the WSDL tool to be refactored as much as
possible so that introduction of new features/changes would require
minimal or no cut and pastes.

Given that the engine is C++, it would be reasonable to have the
restriction of using a C++ compiler for compiling C code. Then one
could raise the question - why not generate C++ code and wrap with C?
I think we have to be clear on why we are going to provide support for
C in order to define the scope of C support. If we say it is for
legacy C integration then we may not need to bother that much about a
pure C interface here - or do we?

Samisa...


On Fri, 10 Dec 2004 10:00:18 +0000, John Hawkins <HA...@uk.ibm.com> wrote:
> 
> 
> Some comments below.
> 
> Overall, I think that we should go with the C to C option and avoid going
> through the C++ layer. It looks too error prone. The only bonus, as far as
> I can tell,  of going through the C++ stubs is that WSDL2WS gets simplified
> but we can still do more refactoring on WSDL2Ws to aid this.
> 
> John Hawkins
> 
> Mark Whitlock/UK/IBM@IBMGB wrote on 09/12/2004 15:43:22:
> 
> 
> 
> >
> >
> >
> >
> > Hi,
> > I'm investigating how to generate the C client stubs. There are two
> > approaches....
> > - Change WSDL2Ws so that it generates C stubs to the new dynamic C client
> > API.
> > - Generate the C stubs as a thin layer on top of the C++ stubs. This
> could
> > be done using the logic from the C binding generator tool that I'm
> > currently developing, driven from WSDL2Ws.
> >
> > Paul Fremantle suggested the second approach and I'm weighing up the two
> > alternatives. Most fixes to WSDL2Ws need to be copied to 4 places: C
> > rpcenc, C doclit, C++ rpcenc and C++ doclit which is error prone. The
> > advantage to the generated C stubs calling the generated C++ stubs is
> that
> > it removed this duplication in WSDL2Ws. Here are some thoughts on
> generated
> > C stubs calling the generated C++ stubs, instead of the dynamic C API....
> >
> > - Client applications that use generated stubs can also use the dynamic
> > client API. Generated stubs inherit methods that allow getting and
> setting
> > of headerblocks, attributes, etc. If generated C stubs call the generated
> > C++ stubs, C applications would have to link with the dynamic C++ API as
> > well as the dynamic C API. This is ok as long as C++ object instances are
> > mapped to C handles in the same way in the generated C stubs as in the
> > dynamic C API.
> >
> > - Complex types are represented by classes in C++ but by structs in C. If
> > the underlying generated C++ stub (de)serializes classes and the
> generated
> > C stub casts these classes to structs, it relies on these generated
> classes
> > and structs having the same length and field offsets for all compilers on
> > all platforms. I tried this on Windows using MS Visual C++ and they were
> > the same length. Can we rely on this? The alternative approach of
> generated
> > C stubs calling the dynamic C API does not rely on this.
> >
> > - Arrays are represented as structs in C and classes in C++ as these also
> > contain the array's length. The C++ implementation should have other
> useful
> > methods that overload operator[ ] and delete the array storage in the
> > destructor. For C++, a better implementation might be to use a template
> so
> > avoiding duplicated code for arrays of different types. Now the C and C++
> > representations really would be different and a C stub could not rely on
> a
> > C++ stub to generate such an array for use in C.
> 
> Not sure that templates are a good thing. I *believe* that templates are
> supported differently on different compilers?
> 
> 
> 
> >
> > - Generated stubs (C++ stubs and the old C stubs) do not deallocate
> storage
> > for output or return parameters. It is up to the application to
> free/delete
> > the storage when appropriate. Storage for output complex objects is
> > allocated in a callback function AXIS_OBJECT_CREATE_FUNCT. So WSDL2Ws
> > generates an implementation of AXIS_OBJECT_CREATE_FUNCT which the client
> > engine calls when it needs to allocate storage for an output complex
> > object. If the generated C stubs call the generated C++ stubs, it will be
> > the generated C++ callback which allocates storage using new (not
> malloc).
> > Later on the C application will have to attempt to free this storage
> using
> > free(). Instead the generated C stubs would have to generate their own
> > callbacks which use malloc/free and then pass them into the generated C++
> > stubs using an extra private API.
> >
> > - There are some places where generated C++ stubs allocate storage using
> > new, for instance in allocating an output array of primitives. Instead
> the
> > generated C++ stubs would have to be aware that they were being called
> from
> > a generated C stub and use malloc instead.
> 
> Oh Yuck ! how complex is this going to be in WSDL2Ws? This sounds like the
> straw that could break the Camels back to me !
> 
> 
> 
> >
> > - I haven't investigated how this would work for C services. Following
> same
> > model, the Axis server would call a generated C++ skeleton which would
> call
> > a generated C skeleton which would call the application code. I am not
> > sufficiently familiar with the server to know if this would work.
> >
> > - C applications would have to be compiled with a C++ compiler if their
> > generated C stubs called generated C++ stubs.
> 
> Not a big issue ? Or would this affect people if we (they) are thinking
> about porting this to a pervasive device?
> 
> 
> >
> > Generated C stubs calling generated C++ stubs is the best approach if...
> > - Users don't mind compiling their C code with a C++ compiler
> > - Classes and their corresponding structs are always the same length for
> > every compiler on every platform
> > - The tool that generates the C stubs is decoupled from WSDL2Ws (although
> > called by it), so that it doesn't break every time changes are made to
> > WSDL2Ws
> > - The generated C++ artifacts can be encapsulated within the generated C
> > artifacts so avoiding any confusion
> > - The server's generated C skeletons can be made to work in a similar way
> >
> > Generated C stubs calling the dynamic C API is the best approach if...
> > - WSDL2Ws could be refactored so every change does not have to be made to
> > the C and C++ support separately
> >
> > Comments?
> > Mark
> > Mark Whitlock
> > IBM
> >
> 
>

Re: Generating C stubs

Posted by John Hawkins <HA...@uk.ibm.com>.



Some comments below.

Overall, I think that we should go with the C to C option and avoid going
through the C++ layer. It looks too error prone. The only bonus, as far as
I can tell,  of going through the C++ stubs is that WSDL2WS gets simplified
but we can still do more refactoring on WSDL2Ws to aid this.




John Hawkins



Mark Whitlock/UK/IBM@IBMGB wrote on 09/12/2004 15:43:22:

>
>
>
>
> Hi,
> I'm investigating how to generate the C client stubs. There are two
> approaches....
> - Change WSDL2Ws so that it generates C stubs to the new dynamic C client
> API.
> - Generate the C stubs as a thin layer on top of the C++ stubs. This
could
> be done using the logic from the C binding generator tool that I'm
> currently developing, driven from WSDL2Ws.
>
> Paul Fremantle suggested the second approach and I'm weighing up the two
> alternatives. Most fixes to WSDL2Ws need to be copied to 4 places: C
> rpcenc, C doclit, C++ rpcenc and C++ doclit which is error prone. The
> advantage to the generated C stubs calling the generated C++ stubs is
that
> it removed this duplication in WSDL2Ws. Here are some thoughts on
generated
> C stubs calling the generated C++ stubs, instead of the dynamic C API....
>
> - Client applications that use generated stubs can also use the dynamic
> client API. Generated stubs inherit methods that allow getting and
setting
> of headerblocks, attributes, etc. If generated C stubs call the generated
> C++ stubs, C applications would have to link with the dynamic C++ API as
> well as the dynamic C API. This is ok as long as C++ object instances are
> mapped to C handles in the same way in the generated C stubs as in the
> dynamic C API.
>
> - Complex types are represented by classes in C++ but by structs in C. If
> the underlying generated C++ stub (de)serializes classes and the
generated
> C stub casts these classes to structs, it relies on these generated
classes
> and structs having the same length and field offsets for all compilers on
> all platforms. I tried this on Windows using MS Visual C++ and they were
> the same length. Can we rely on this? The alternative approach of
generated
> C stubs calling the dynamic C API does not rely on this.
>
> - Arrays are represented as structs in C and classes in C++ as these also
> contain the array's length. The C++ implementation should have other
useful
> methods that overload operator[ ] and delete the array storage in the
> destructor. For C++, a better implementation might be to use a template
so
> avoiding duplicated code for arrays of different types. Now the C and C++
> representations really would be different and a C stub could not rely on
a
> C++ stub to generate such an array for use in C.

Not sure that templates are a good thing. I *believe* that templates are
supported differently on different compilers?

>
> - Generated stubs (C++ stubs and the old C stubs) do not deallocate
storage
> for output or return parameters. It is up to the application to
free/delete
> the storage when appropriate. Storage for output complex objects is
> allocated in a callback function AXIS_OBJECT_CREATE_FUNCT. So WSDL2Ws
> generates an implementation of AXIS_OBJECT_CREATE_FUNCT which the client
> engine calls when it needs to allocate storage for an output complex
> object. If the generated C stubs call the generated C++ stubs, it will be
> the generated C++ callback which allocates storage using new (not
malloc).
> Later on the C application will have to attempt to free this storage
using
> free(). Instead the generated C stubs would have to generate their own
> callbacks which use malloc/free and then pass them into the generated C++
> stubs using an extra private API.
>
> - There are some places where generated C++ stubs allocate storage using
> new, for instance in allocating an output array of primitives. Instead
the
> generated C++ stubs would have to be aware that they were being called
from
> a generated C stub and use malloc instead.

Oh Yuck ! how complex is this going to be in WSDL2Ws? This sounds like the
straw that could break the Camels back to me !

>
> - I haven't investigated how this would work for C services. Following
same
> model, the Axis server would call a generated C++ skeleton which would
call
> a generated C skeleton which would call the application code. I am not
> sufficiently familiar with the server to know if this would work.
>
> - C applications would have to be compiled with a C++ compiler if their
> generated C stubs called generated C++ stubs.

Not a big issue ? Or would this affect people if we (they) are thinking
about porting this to a pervasive device?
>
> Generated C stubs calling generated C++ stubs is the best approach if...
> - Users don't mind compiling their C code with a C++ compiler
> - Classes and their corresponding structs are always the same length for
> every compiler on every platform
> - The tool that generates the C stubs is decoupled from WSDL2Ws (although
> called by it), so that it doesn't break every time changes are made to
> WSDL2Ws
> - The generated C++ artifacts can be encapsulated within the generated C
> artifacts so avoiding any confusion
> - The server's generated C skeletons can be made to work in a similar way
>
> Generated C stubs calling the dynamic C API is the best approach if...
> - WSDL2Ws could be refactored so every change does not have to be made to
> the C and C++ support separately
>
> Comments?
> Mark
> Mark Whitlock
> IBM
>


Re: Generating C stubs

Posted by Nadir Amra <am...@us.ibm.com>.
Although I do not have in-depth knowledge of AXIS C++ framework as of yet, 
this support is very important to the OS/400 platform.  So I will talk 
about things in general terms and indicate what I would like to see in the 
implementation, in addition to answering some of your questions.

First, I hope the framework that we come up with is flexible enough so 
that other languages (e.g. COBOL, RPG) may possibly be supported.  Right 
now I am thinking that applications written in these languages can always 
invoke the C stubs, but in the future, one might be inclined to create 
stubs written in COBOL and RPG or any other language.  So any design 
should be general enough to go beyond the C language if possible. 

I assume the handle is an opaque handle that (void pointer) that is just 
passed on to the AXIS engine.

I assume that simple data types are individual parameters, not structures? 
 

You definitely cannot assume that generated classes and structs have the 
same length and field offsets for all compilers on all platforms.

It would be nice for allocated storage returned to C application for 
return values be tied to the handle, and that Axis provides an API that 
includes the handle and storage to free the allocated storage?  Thus, if 
client want to free the handle, the Axis code can then go through the 
allocated storage list and perform the necessary deallocations. 

We do need to be consistent on whether we use 'new' or 'malloc' when 
allocating storage. On some platforms you cannot use 'free' to deallocated 
new'ed storage and vice versa - you cannot use delete to deallocate 
malloc'ed storage.  If we do not provide an API for applications to call 
to free the storage, then it would have to be malloc in order for a C 
application to free the storage. 

I think the focus should be on the C client end.  C services can be done 
if there is time, or in another release.

I believe that I would urge going the "Generated C stubs calling the 
dynamic C API is the best approach".  This seems to me the cleanest 
approach. 

It would also be nice to have some simple examples of the stubs and how a 
client would invoke the stubs just to see how things would look.





Mark Whitlock <ma...@uk.ibm.com> 
12/09/2004 09:43 AM
Please respond to
"Apache AXIS C Developers List"


To
axis-c-dev@ws.apache.org
cc

Subject
Generating C stubs










Hi,
I'm investigating how to generate the C client stubs. There are two
approaches....
- Change WSDL2Ws so that it generates C stubs to the new dynamic C client
API.
- Generate the C stubs as a thin layer on top of the C++ stubs. This could
be done using the logic from the C binding generator tool that I'm
currently developing, driven from WSDL2Ws.

Paul Fremantle suggested the second approach and I'm weighing up the two
alternatives. Most fixes to WSDL2Ws need to be copied to 4 places: C
rpcenc, C doclit, C++ rpcenc and C++ doclit which is error prone. The
advantage to the generated C stubs calling the generated C++ stubs is that
it removed this duplication in WSDL2Ws. Here are some thoughts on 
generated
C stubs calling the generated C++ stubs, instead of the dynamic C API....

- Client applications that use generated stubs can also use the dynamic
client API. Generated stubs inherit methods that allow getting and setting
of headerblocks, attributes, etc. If generated C stubs call the generated
C++ stubs, C applications would have to link with the dynamic C++ API as
well as the dynamic C API. This is ok as long as C++ object instances are
mapped to C handles in the same way in the generated C stubs as in the
dynamic C API.

- Complex types are represented by classes in C++ but by structs in C. If
the underlying generated C++ stub (de)serializes classes and the generated
C stub casts these classes to structs, it relies on these generated 
classes
and structs having the same length and field offsets for all compilers on
all platforms. I tried this on Windows using MS Visual C++ and they were
the same length. Can we rely on this? The alternative approach of 
generated
C stubs calling the dynamic C API does not rely on this.

- Arrays are represented as structs in C and classes in C++ as these also
contain the array's length. The C++ implementation should have other 
useful
methods that overload operator[ ] and delete the array storage in the
destructor. For C++, a better implementation might be to use a template so
avoiding duplicated code for arrays of different types. Now the C and C++
representations really would be different and a C stub could not rely on a
C++ stub to generate such an array for use in C.

- Generated stubs (C++ stubs and the old C stubs) do not deallocate 
storage
for output or return parameters. It is up to the application to 
free/delete
the storage when appropriate. Storage for output complex objects is
allocated in a callback function AXIS_OBJECT_CREATE_FUNCT. So WSDL2Ws
generates an implementation of AXIS_OBJECT_CREATE_FUNCT which the client
engine calls when it needs to allocate storage for an output complex
object. If the generated C stubs call the generated C++ stubs, it will be
the generated C++ callback which allocates storage using new (not malloc).
Later on the C application will have to attempt to free this storage using
free(). Instead the generated C stubs would have to generate their own
callbacks which use malloc/free and then pass them into the generated C++
stubs using an extra private API.

- There are some places where generated C++ stubs allocate storage using
new, for instance in allocating an output array of primitives. Instead the
generated C++ stubs would have to be aware that they were being called 
from
a generated C stub and use malloc instead.

- I haven't investigated how this would work for C services. Following 
same
model, the Axis server would call a generated C++ skeleton which would 
call
a generated C skeleton which would call the application code. I am not
sufficiently familiar with the server to know if this would work.

- C applications would have to be compiled with a C++ compiler if their
generated C stubs called generated C++ stubs.

Generated C stubs calling generated C++ stubs is the best approach if...
- Users don't mind compiling their C code with a C++ compiler
- Classes and their corresponding structs are always the same length for
every compiler on every platform
- The tool that generates the C stubs is decoupled from WSDL2Ws (although
called by it), so that it doesn't break every time changes are made to
WSDL2Ws
- The generated C++ artifacts can be encapsulated within the generated C
artifacts so avoiding any confusion
- The server's generated C skeletons can be made to work in a similar way

Generated C stubs calling the dynamic C API is the best approach if...
- WSDL2Ws could be refactored so every change does not have to be made to
the C and C++ support separately

Comments?
Mark
Mark Whitlock
IBM