473,327 Members | 1,896 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

C++ callback function passed to a C program

Hi all,

is there any trouble setting an C++ static class method as callback
function for a C program or library ?

Thanks
Jul 19 '05 #1
6 5299
Eric Entressangle wrote:
Hi all,

is there any trouble setting an C++ static class method as callback
function for a C program or library ?


Yes. The function will have C++ calling conventions, but be called using
C calling conventions. An some (many?) compilers, they are both the
same, but if they differ, it won't work. For maximum portability, you
should only use extern "C" functions for that, which is of course not
possible for member functions, even if static.

Jul 19 '05 #2
On Fri, 25 Jul 2003 18:22:21 +0200, Rolf Magnus <ra******@t-online.de> wrote:
Eric Entressangle wrote:
Hi all,

is there any trouble setting an C++ static class method as callback
function for a C program or library ?


Yes. The function will have C++ calling conventions, but be called using
C calling conventions. An some (many?) compilers, they are both the
same, but if they differ, it won't work. For maximum portability, you
should only use extern "C" functions for that, which is of course not
possible for member functions, even if static.


Using an 'extern "C"' function doesn't buy additional portability... ;-)

Reason: neither C nor C++ defines the machine-level calling convention,
nor name-mangling or other relevant things. With at least one of the
most used C and C++ compilers 'extern "C"' has _no_ effect on the
calling convention whatsoever. What it does influence with that
compiler is the name mangling, i.e. linkage compatibility: the compiler
trusts you to know what you're doing, since this spec removes type
information (e.g. name mangling) in order to be linkage-compatible
with C.

The main assumption for the callback problem is calling convention
compatibility, and linkage compatibility doesn't enter the picture, but
the details of the calling convention compatibility depends on the
compilers, and one should not assume that 'extern "C"' will influence
calling conventions, data type compatibility, or any such thing.

Jul 19 '05 #3
On Fri, 25 Jul 2003 19:54:33 +0200, Rolf Magnus <ra******@t-online.de> wrote:

Reason: neither C nor C++ defines the machine-level calling
convention, nor name-mangling or other relevant things.
I'm aware of that.


Then you should draw the logical conclusions from that,

[Silly and longish irrelevant quoting of the standard elided]From the standard's POV,
POV?

those things [calling convention, data types etc.] are all part
of the linkage.
Even different versions of the same C++ compiler can produce
incompatible object code, in full agreement with the standard.
So in other words, what you write is not correct.
Anyway, what would you gain if your compiler use the correct naming for
the functions for calling them from C, if the data types aren't
compatible or the parameters are passed differently?


You'd have to ask Kernighan and Ritchie about that... For in C you can
have (or at least could have) incompatibility between calling code
and called code even within the same compilation unit; hence the tendency
of C programmers to write "int main(void)", because simply leaving out the
argument list for a function would match any signature. When C++ is
interfaced to C there is no way the C++ standard can compensate, and so
it does not even try.

On a more practical level it's _your_ job to make sure that everyhing
matches between call and called function.

Achieving linking is just one of many considerations, and furthermore,
is not relevant to using a C++ function as a callback.

Jul 19 '05 #4
Alf P. Steinbach wrote:
On Fri, 25 Jul 2003 19:54:33 +0200, Rolf Magnus <ra******@t-online.de>
wrote:

Reason: neither C nor C++ defines the machine-level calling
convention, nor name-mangling or other relevant things.
I'm aware of that.


Then you should draw the logical conclusions from that,

[Silly and longish irrelevant quoting of the standard elided]
From the standard's POV,


POV?


Point Of View

those things [calling convention, data types etc.] are all part
of the linkage.
Even different versions of the same C++ compiler can produce
incompatible object code, in full agreement with the standard.
So in other words, what you write is not correct.


But the part of the standard I quoted just says that.
Anyway, what would you gain if your compiler use the correct naming
for the functions for calling them from C, if the data types aren't
compatible or the parameters are passed differently?


You'd have to ask Kernighan and Ritchie about that... For in C you
can have (or at least could have) incompatibility between calling code
and called code even within the same compilation unit; hence the
tendency of C programmers to write "int main(void)", because simply
leaving out the argument list for a function would match any
signature.


AFAIK, this is due to historical reasons. In C99, it's not true anymore.
When C++ is interfaced to C there is no way the C++ standard can
compensate, and so it does not even try.
Well, it doesn't say how the linkage looks like, but it says that the
compiler _must_ offer C linkage. Most C++ compilers also understand C
or are bundled with a C compiler, and I would be quite surprised if
they wouldn't just make their C linkage compatible with the C compiler.
On a more practical level it's _your_ job to make sure that everyhing
matches between call and called function.
Well, it's "my" job to make sure that the compilers agree about their C
linkage style.
Achieving linking is just one of many considerations, and furthermore,
is not relevant to using a C++ function as a callback.


Look again at the OP's question. He asked about static members as
callback for a C program or library. And so it definitely is relevant.
That was my point anyway. I just answered that making the callback
function extern "C" is the most portable solution. Do you disagree
about that?
Jul 19 '05 #5
On Fri, 25 Jul 2003 21:59:28 +0200, Rolf Magnus <ra******@t-online.de> wrote:
Alf P. Steinbach wrote:
On Fri, 25 Jul 2003 19:54:33 +0200, Rolf Magnus <ra******@t-online.de>
wrote:

Reason: neither C nor C++ defines the machine-level calling
convention, nor name-mangling or other relevant things.

I'm aware of that.


Then you should draw the logical conclusions from that,

[Silly and longish irrelevant quoting of the standard elided]
From the standard's POV,


POV?


Point Of View

those things [calling convention, data types etc.] are all part
of the linkage.


Even different versions of the same C++ compiler can produce
incompatible object code, in full agreement with the standard.
So in other words, what you write is not correct.


But the part of the standard I quoted just says that.


???

Anyway, what would you gain if your compiler use the correct naming
for the functions for calling them from C, if the data types aren't
compatible or the parameters are passed differently?


You'd have to ask Kernighan and Ritchie about that... For in C you
can have (or at least could have) incompatibility between calling code
and called code even within the same compilation unit; hence the
tendency of C programmers to write "int main(void)", because simply
leaving out the argument list for a function would match any
signature.


AFAIK, this is due to historical reasons. In C99, it's not true anymore.


Keep in mind that the C++ standard stems from 1997, and that 1997 < 1999.
When C++ is interfaced to C there is no way the C++ standard can
compensate, and so it does not even try.


Well, it doesn't say how the linkage looks like, but it says that the
compiler _must_ offer C linkage. Most C++ compilers also understand C
or are bundled with a C compiler, and I would be quite surprised if
they wouldn't just make their C linkage compatible with the C compiler.


As a concrete example, Visual C++ supports a number of different
calling conventions such as "__stdcall" (which oldtimers like me think
of as Pascal) and "__cdecl" (which we think of as "C", purely because
of typical usage). If you decorate a function with 'extern "C"',
then (with this widely used compiler) that does _not_ affect the
calling convention. It affects only the external name the linker sees
(wrt. to the standard there's not necessarily a linker involved, but
this scheme is, as far as I know, completely standard-conforming.)

The crux is that there's no such thing as "the" C compiler.

There are a number of different C compilers, and even using just one
compiler you can compile functions that look the same to the linker
(and so, no amount of fiddling in C++ can guarantee compatibility) but
which have different calling conventions, different sizes of int, or
whatever.

On a more practical level it's _your_ job to make sure that everyhing
matches between call and called function.


Well, it's "my" job to make sure that the compilers agree about their C
linkage style.


Yep.

Achieving linking is just one of many considerations, and furthermore,
is not relevant to using a C++ function as a callback.


Look again at the OP's question. He asked about static members as
callback for a C program or library. And so it definitely is relevant.
That was my point anyway. I just answered that making the callback
function extern "C" is the most portable solution. Do you disagree
about that?


Yep.

Jul 19 '05 #6
Alf P. Steinbach wrote:
But the part of the standard I quoted just says that.
???


I can repeat that quote again, though I don't know why you don't just
read it in my previous posting. So again, I said:
those things [calling convention, data types etc.] are all part
of the linkage.
And you said:
Even different versions of the same C++ compiler can produce
incompatible object code, in full agreement with the standard.
to which I agree, but not to:
So in other words, what you write is not correct.
I quoted the following sentence from the standard:

All function types, function names and variable names have a language
linkage. [Note: Some of the properties associated with an entity with
language linkage may be associated with a particular form of
representing names of objects and functions with external linkage, or
with a particular calling convention, etc. ]

It says that "a particular calling convetion, etc." is no less part of
the "language linkage" than "a particular form of representing names of
objects and functions with external linkage". That's what I said above
and you claimed to be "not correct".

Besides that, of course the code is not compatible with every C
compiler, but from what I read from the standard (Every implementation
shall provide for linkage to functions written in the C programming
language, "C", and linkage to C++ functions, "C++".), there must be at
least one C compiler that it's compatible with. How else would the
compiler be able to "provide linkage to functions written in the C
programming language"?
You'd have to ask Kernighan and Ritchie about that... For in C you
can have (or at least could have) incompatibility between calling
code and called code even within the same compilation unit; hence
the tendency of C programmers to write "int main(void)", because
simply leaving out the argument list for a function would match any
signature.


AFAIK, this is due to historical reasons. In C99, it's not true
anymore.


Keep in mind that the C++ standard stems from 1997, and that 1997 <
1999.


What does that have to do with each other?
When C++ is interfaced to C there is no way the C++ standard can
compensate, and so it does not even try.


Well, it doesn't say how the linkage looks like, but it says that the
compiler _must_ offer C linkage. Most C++ compilers also understand C
or are bundled with a C compiler, and I would be quite surprised if
they wouldn't just make their C linkage compatible with the C
compiler.


As a concrete example, Visual C++ supports a number of different
calling conventions such as "__stdcall" (which oldtimers like me think
of as Pascal) and "__cdecl" (which we think of as "C", purely because
of typical usage). If you decorate a function with 'extern "C"',
then (with this widely used compiler) that does _not_ affect the
calling convention. It affects only the external name the linker sees
(wrt. to the standard there's not necessarily a linker involved, but
this scheme is, as far as I know, completely standard-conforming.)

The crux is that there's no such thing as "the" C compiler.


Yes, that seems to be a quality-of-implementation issue. But as I said,
I'd expect from a C++ compiler that is bundled with a C compiler that
by default both use the same C "language linkage", including calling
conventions.
There are a number of different C compilers, and even using just one
compiler you can compile functions that look the same to the linker
(and so, no amount of fiddling in C++ can guarantee compatibility) but
which have different calling conventions, different sizes of int, or
whatever.


Yes. What's your point?
Achieving linking is just one of many considerations, and
furthermore, is not relevant to using a C++ function as a callback.


Look again at the OP's question. He asked about static members as
callback for a C program or library. And so it definitely is relevant.
That was my point anyway. I just answered that making the callback
function extern "C" is the most portable solution. Do you disagree
about that?


Yep.


Ok, so what would be more portable then?

Jul 19 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: vijaya | last post by:
I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.The unmanaged dll fucntion is as follows **************************************** The Original Fucntion in the dll...
8
by: Ash | last post by:
Hello all, I am hoping this is the appropriate newsgroup for a C++ interface design question. I am trying to design an interface for a subscriber to register/deregister handlers for various...
4
by: ma740988 | last post by:
// file sltest.h #ifndef SLTEST_H #define SLTEST_H class CallbackBase // herb shutters gotW source .. { public: virtual void operator()() const { }; virtual ~CallbackBase() = 0; };
15
by: Felix Kater | last post by:
Hi, in a given library I register callback functions with this function: bool set_callback(int index, int (*callback_function)(long)); I need the callback function to also pass the index...
2
by: MR | last post by:
help! I have an unmanaged DLL that I do not have the source code, so i can't recompile or make changes. the DLL requires a callback function. I would like to implement the callback method in a...
0
by: Boltar | last post by:
Hello, I am trying to use a CustomValidator control to perform client-side validation via a server callback. I have an example below that validates if a textbox contains an odd number. I...
4
by: Edwin Gomez | last post by:
I'm a C# developer and I'm new to Python. I would like to know if the concept of Asynchronous call-backs exists in Python. Basically what I mean is that I dispatch a thread and when the thread...
6
by: smmk25 | last post by:
Before I state the problem, I just want to let the readers know, I am knew to C++\CLI and interop so please forgive any newbie questions. I have a huge C library which I want to be able to use in...
5
by: Jef Driesen | last post by:
I have a C DLL that I want to use from a C# project. The C header file contains these declarations: typedef void (*callback_t) (const unsigned char *data, unsigned int size, void *userdata);...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.