axis-c-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Whitlock <>
Subject Fw: Generating C stubs
Date Mon, 13 Dec 2004 15:19:17 GMT

Thank you Samisa, John and Nadir for your comments.

Based on your comments I will generate C stubs to use the dynamic C API,
not the generated C++ stubs. I know Adrian is hoping to do some work
refactoring WSDL2Ws so I will work with him to simplify the tool if
possible. More comments below...
Mark Whitlock

Nadir wrote ..........

> 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.
Right now I'm only focussing on C and C++ support, but I'll bear this in

> I assume the handle is an opaque handle that (void pointer) that is just
passed on to the AXIS engine.
Yes, handles are opaque to applications and resolved to C++ class instances
by the C bindings.

> I assume that simple data types are individual parameters, not
Yes, simple datatypes will be the same in C as in C++. As in C++, nillable
types are represented as a pointer to that type. So a nillable xsd_int is
represented as a int* in C and C++.

> You definitely cannot assume that generated classes and structs have the
same length and field offsets for all compilers on
>  all platforms.
I think I didn't explain myself properly. What I meant was that on any
particular platform, is it safe to assume that the generated classes and
generated structs have the same length and field offsets. Anyhow this does
not matter if the generated C stubs call the dynamic C API.

> 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.
The C destroy functions will map to C++ destructors, so the memory model is
the same for C and C++. Some storage is freed by the destructor (~Stub
deletes m_pCall), whereas other storage is left for the application to free
(storage for output complex objects). Storage that is freed by destructors
(~Stub for instance) will be new'ed by axis, used by the application
(either C or C++) and deleted by the destructor of whichever axis class
owns the storage. Storage that is freed by C applications will be new'ed by
the axis engine and then will be copied into malloc'ed storage by the C
bindings and the original new'ed storage deleted immediately. The C
application can free() this storage later. C destroy functions will call
C++ destructors, to destroy handles, but it seems the C destroy function
won't actually need to free much other storage. So something like extern C
destroyCall(AXISCHANDLE callHandle) { delete (Call)callHandle; }

> 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
>  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
The C bindings will be careful to get this right.

> I think the focus should be on the C client end.  C services can be done
if there is time, or in another release.
Yes I will implement the C client API first, then generated C stubs.

> 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.
I'll post some examples to the mailing list soon.

 Mark Whitlock <>                                  
 12/09/2004 09:43 AM                                   axis-c-dev@ws.apach 
              Please respond to                                            
       "Apache AXIS C Developers List"                             Subject 
                                                       Generating C stubs  

I'm investigating how to generate the C client stubs. There are two
- Change WSDL2Ws so that it generates C stubs to the new dynamic C client
- 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
- 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

Mark Whitlock

View raw message