Topic: The use of static memberfunctions as C-callback functions
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sat, 14 May 1994 11:34:36 GMT Raw View
In article <KANZE.94May10145316@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
>In article <2qiri0$c5@motif.hacktic.nl> rvloon@motif.hacktic.nl
>(Ronald van Loon) writes:
>
> [Concerning call-back functions in window systems...]
>
>|> what does the `standard' have to say about the portability of the methods
>|> above?
>
>That all three are implementation dependant:-)?
>
>calling sequences. For that matter, there is no guarantee that two
>different versions of the C compiler from the same vendor use the same
>calling sequence, or that programs compiled with different compiler
>options will use compatible calling sequences. This is notably a
>problem under MS-DOS.)
No, it is not a problem under MS-DOS, on the contrary,
MS-Windows establishes a rigorous Standard of external interfacing
that all vendors supporting Windows must comply with.
The fact that the call back uses a horrible long
description with
extern "C"
far
pascal
export
as qualifiers is ghastly and differs from compiler to compiler,
but all must provide these facilities or access to Windows is impossible.
So its one of the few things for which portability is NOT a hard problem.
The BIG problem is that Windows itself CANNOT properly support
association of objects with Windows. (X-Windows can). So, various
tricks, hacks and Kludges are required.
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd, CSERVE:10236.1703
6 MacKay St ASHFIELD, Mem: SA IT/9/22,SC22/WG21
NSW 2131, AUSTRALIA
Author: rvloon@motif.hacktic.nl (Ronald van Loon)
Date: 8 May 1994 14:04:48 -0000 Raw View
At the moment there is a discussion in the various comp.windows.x.* groups
about the portability of using static memberfunctions for C-code fragments
that use a callback mechanism.
Let me describe the dilemma first:
in window systems there's the notion of event-handling: the system has a set
of specific events that it can send to an application; these events can either
have a type field, which usually leads to switch statements of gigantic
proportions, or they can use the notion of a callback-function for each
distinctive event-type, for which the application can register a function -
this is comparable to the set_new_handler() mechanism.
Whatever form is chosen, in both cases an application function is called. Most
window-systems APIs are written in C, and therefore require their functions to
be C-functions, functions that honor the C calling conventions of handling
parameters (with the exception of MS-Windows, which, if I remember correctly,
requires a Pascal calling convention).
In C++, things are handled differently: switch-statements are frowned upon,
and most of the functionality required for handling events can be implemented
through virtual memberfunctions. Yet, those functions cannot be used directly
by the C-based implementation of libraries, because of the implicit `this'
pointer.
So, there are basically three solutions possible:
1- use a non-member function with `extern "C"' linkage.
2- use a non-member function without explicit `extern "C"' linkage. (in
effect, with possible C++ linkage, but not belonging to any class)
3- use a static member function; a static member function does not have
an implicit `this' pointer, and therefore can be treated much the same
as a non-member function without `extern "C"' linkage, but by being a class
member, still showing its affiliation with a specific class of objects.
Whatever option is chosen, all functions should proceed by obtaining a pointer
to a class object and then calling the appropriate (virtual) member-function
for that object.
Option (1) should work at all times of course, because of the directive given;
in my experience with a multitude of compilers, options (2) and (3) also work.
(3) is my option of choice, because it is more intuitive and more
object-oriented. It also has the advantage that no `friend' directives are
necessary in order to obtain access to private or protected memberfunctions.
Yet, some people claim that options (2) and (3) are not portable across
architectures/compilers.
Now, for my question:
what does the `standard' have to say about the portability of the methods
above?
--
Ronald van Loon \ S-Mail: St. Janskerkhof 18 / Even when you're
- Motif++ Maintainer \ 3811 HW Amersfoort / on the right track
- Columnist C++ Report \ The Netherlands / you'll get run over
(rvloon@motif.hacktic.nl) \ Phone: +31 33 758 293 / if you just sit there
Author: kanze@us-es.sel.de (James Kanze)
Date: 10 May 1994 13:53:16 GMT Raw View
In article <2qiri0$c5@motif.hacktic.nl> rvloon@motif.hacktic.nl
(Ronald van Loon) writes:
[Concerning call-back functions in window systems...]
|> So, there are basically three solutions possible:
|> 1- use a non-member function with `extern "C"' linkage.
|> 2- use a non-member function without explicit `extern "C"' linkage. (in
|> effect, with possible C++ linkage, but not belonging to any class)
|> 3- use a static member function; a static member function does not have
|> an implicit `this' pointer, and therefore can be treated much the same
|> as a non-member function without `extern "C"' linkage, but by being a class
|> member, still showing its affiliation with a specific class of objects.
|> Whatever option is chosen, all functions should proceed by obtaining a pointer
|> to a class object and then calling the appropriate (virtual) member-function
|> for that object.
|> Option (1) should work at all times of course, because of the directive given;
|> in my experience with a multitude of compilers, options (2) and (3) also work.
|> (3) is my option of choice, because it is more intuitive and more
|> object-oriented. It also has the advantage that no `friend' directives are
|> necessary in order to obtain access to private or protected memberfunctions.
|> Yet, some people claim that options (2) and (3) are not portable across
|> architectures/compilers.
|> Now, for my question:
|> what does the `standard' have to say about the portability of the methods
|> above?
That all three are implementation dependant:-)?
In fact, it doesn't say much. But the ascribed purpose of the
``extern "C"'' specification is precisely to make this work; IF the C
and the C++ compiler come from the same vendor, I would consider it a
bug if they didn't work. Note the *big* if, though. (On the other
hand, this same if exists even in the absense of C. There is no
guarantee that two different vendors' C compilers use compatible
calling sequences. For that matter, there is no guarantee that two
different versions of the C compiler from the same vendor use the same
calling sequence, or that programs compiled with different compiler
options will use compatible calling sequences. This is notably a
problem under MS-DOS.)
As for options 2 and 3, there is no reason to suppose that they might
work. But then again, there is nothing from preventing a vendor from
making them work. Again, I would expect the most problems on Intel
architecture; in fact, I know of at least one compiler where they will
*not* work.
If I were writing a C++ compiler for MS-DOS, options 2 and 3 would not
work for it. But if I were writing a C++ compiler for MS-Windows, I
would also provide an interface library where you register objects
(functors), not call-back functions, so it wouldn't matter (except
that I would have to solve the problem in my library:-).
--
James Kanze email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung