Go Back   Coding Forum > Coding World > C++ / CPP

Reply
 
LinkBack Thread Tools Display Modes
Old 06-02-2015, 05:30 AM   #1 (permalink)
Lane
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

I'm using a C api within the C++ MyClass. This works, but I'd like to be
able to use the private fields (varX) within these callbacks. Is there
anyway to make the callbacks look like class member functions?

Currently, things look like the following.

// file1.cpp
void read_callback(Dev *dev, const MyData *t)
{
// do stuff ...
}

// file2.cpp
class MyClass
{
private:
Dev *dev;
DevListener dl;

// how to use these in the callback?
int var1;
long var2;
string var3;
double var4;

public:
MyClass();
~MyClass();

void operator()() {

try {

dl.listener = read_callback;

ret = Dev_addListener(dev, &dl);
// ...

ret = Dev_start_async_reads(dev);
// ...
}
catch (const exception& e) {
// exception
}
}
};
  Reply With Quote
Old 06-02-2015, 05:30 AM   #2 (permalink)
LĹ‘rinczy Zsigmond
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

On 2015.06.02. 7:03, Lane wrote:
> I'm using a C api within the C++ MyClass. This works, but I'd like to be
> able to use the private fields (varX) within these callbacks. Is there
> anyway to make the callbacks look like class member functions?


If the caller of the callback is passing a 'user-parameter'
to the callback, then a static method might work:
the user-parameter will be the address of the object.

Example (with Hungarian comments):
http://web.axelero.hu/lzsiga/cback.cc

  Reply With Quote
Old 06-02-2015, 06:30 AM   #3 (permalink)
Paavo Helde
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

Lane <software.research.development@gmail.com> wrote in news:mkjda812947
@news3.newsguy.com:

> I'm using a C api within the C++ MyClass. This works, but I'd like to be
> able to use the private fields (varX) within these callbacks. Is there
> anyway to make the callbacks look like class member functions?


(1) You can declare callback functions as friends.

(2) You can add public member functions to your class which are called by
the callback functions. A bit more tedious, but clearer in the long run.

The drawback with (2) is that these member functions are typically not
really "public". A way to cope with that is to add comments like

public: // implementation

and use some naming schema like Foo_impl() in the method names to indicate
these are not to be called willy-nilly.

The static member function approach suggested by another poster is similar
to (1), but a bit unportable (the static member function linkage may or may
not be compatible with the C linkage assumed by the C API). To be fully
portable one needs to use extern "C" callback functions with a C API, and
(static) member functions cannot be declared extern "C".

  Reply With Quote
Old 06-02-2015, 01:30 PM   #4 (permalink)
Cholo Lennon
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

On 06/02/2015 02:56 AM, Paavo Helde wrote:

> The static member function approach suggested by another poster is similar
> to (1), but a bit unportable (the static member function linkage may or may
> not be compatible with the C linkage assumed by the C API). To be fully
> portable one needs to use extern "C" callback functions with a C API, and
> (static) member functions cannot be declared extern "C".
>


Could you explain a bit more about portability problems? I've always
used static member functions as C library callbacks...

TIA



--
Cholo Lennon
Bs.As.
ARG
  Reply With Quote
Old 06-02-2015, 02:30 PM   #5 (permalink)
Martin Shobe
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

On 6/2/2015 7:44 AM, Cholo Lennon wrote:
> On 06/02/2015 02:56 AM, Paavo Helde wrote:
>> The static member function approach suggested by another poster is
>> similar
>> to (1), but a bit unportable (the static member function linkage may
>> or may
>> not be compatible with the C linkage assumed by the C API). To be fully
>> portable one needs to use extern "C" callback functions with a C API, and
>> (static) member functions cannot be declared extern "C".


> Could you explain a bit more about portability problems? I've always
> used static member functions as C library callbacks...


I don't know of any implementations that do this, but one could have an
implementation that uses one calling convention, say everything on the
stack, for extern "C" functions while the static member functions use a
different one, say the first three in registers with the rest on the
stack. This would cause problems when attempting to call the static
member function from C library. For the example, the first three
arguments would be whatever happened to be in those registers at the
time of the call, the fourth parameter would contain the first
parameter's data[1], etc.

Martin Shobe

[1] This isn't exactly right. We might have objects of different sizes
that keep them from lining up so nicely. You should still get the idea
of why it's not portable to use static member functions as C library
callbacks.

  Reply With Quote
Old 06-02-2015, 06:30 PM   #6 (permalink)
Paavo Helde
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

Cholo Lennon <chololennon@hotmail.com> wrote in
news:mkk8ff$p3o$4@speranza.aioe.org:

> On 06/02/2015 02:56 AM, Paavo Helde wrote:
>
>> The static member function approach suggested by another poster is
>> similar to (1), but a bit unportable (the static member function
>> linkage may or may not be compatible with the C linkage assumed by
>> the C API). To be fully portable one needs to use extern "C" callback
>> functions with a C API, and (static) member functions cannot be
>> declared extern "C".
>>

>
> Could you explain a bit more about portability problems? I've always
> used static member functions as C library callbacks...


Yes, there appears to be no problem with most (all?) existing C++
implementations and all new implementations will probably have to follow
the suite too to avoid breaking tons of code. Nevertheless, this approach
is not guaranteed to work by the standard because C functions and C++
static member functions are not guaranteed to use the same calling
conventions.

Some compilers like MSVC have extensions for specifying calling conventions
also for static member functions. One can e.g. declare a __stdcall static
member function which can then be used as a callback function with certain
Windows SDK functions. These extensions are of course non-portable as well.
  Reply With Quote
Old 06-02-2015, 06:30 PM   #7 (permalink)
Paavo Helde
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

legalize+jeeves@mail.xmission.com (Richard) wrote in
news:mkkqg9$uik$2@news.xmission.com:

> [Please do not mail me a copy of your followup]
>
> Paavo Helde <myfirstname@osa.pri.ee> spake the secret code
> <XnsA4AD5AFEE74C6myfirstnameosapriee@216.166.105.1 31> thusly:
>
>>The static member function approach suggested by another poster is
>>similar to (1), but a bit unportable (the static member function
>>linkage may or may not be compatible with the C linkage assumed by the
>>C API).

>
> This is just plain wrong; you don't understand how the linkage is
> working in this case. There is no C code linking explicitly to your
> callback functions, they only appear inside a C++ linkage context.


This is not about name mangling when linking, this is about the calling
conventions. The extern "C" thingy affects both in principle.

  Reply With Quote
Old 06-02-2015, 06:30 PM   #8 (permalink)
Paavo Helde
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

Paavo Helde <myfirstname@osa.pri.ee> wrote in
news:XnsA4ADD7F1A4724myfirstnameosapriee@216.166.1 05.131:

> legalize+jeeves@mail.xmission.com (Richard) wrote in
> news:mkkqg9$uik$2@news.xmission.com:
>
>> [Please do not mail me a copy of your followup]
>>
>> Paavo Helde <myfirstname@osa.pri.ee> spake the secret code
>> <XnsA4AD5AFEE74C6myfirstnameosapriee@216.166.105.1 31> thusly:
>>
>>>The static member function approach suggested by another poster is
>>>similar to (1), but a bit unportable (the static member function
>>>linkage may or may not be compatible with the C linkage assumed by the
>>>C API).

>>
>> This is just plain wrong; you don't understand how the linkage is
>> working in this case. There is no C code linking explicitly to your
>> callback functions, they only appear inside a C++ linkage context.

>
> This is not about name mangling when linking, this is about the calling
> conventions. The extern "C" thingy affects both in principle.


This is also covered by a FAQ:
https://isocpp.org/wiki/faq/pointers...fnptr-vs-fnptr

"Note: static member functions do not require an actual object to be
invoked, so pointers-to-static-member-functions are usually type-
compatible with regular pointers-to-functions. However, although it
probably works on most compilers, it actually would have to be an extern
"C" non-member function to be correct, since “C linkage” doesn’t only
cover things like name mangling, but also calling conventions, which
might be different between C and C++."



  Reply With Quote
Old 06-02-2015, 07:30 PM   #9 (permalink)
Ian Collins
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

Richard wrote:
> [Please do not mail me a copy of your followup]
>
> Paavo Helde <myfirstname@osa.pri.ee> spake the secret code
> <XnsA4AD5AFEE74C6myfirstnameosapriee@216.166.105.1 31> thusly:
>
>> Lane <software.research.development@gmail.com> wrote in news:mkjda812947
>> @news3.newsguy.com:
>>
>>> I'm using a C api within the C++ MyClass. This works, but I'd like to be
>>> able to use the private fields (varX) within these callbacks. Is there
>>> anyway to make the callbacks look like class member functions?

>>
>> (1) You can declare callback functions as friends.

>
> Please god, no. Friend use is abuse most of the time and it is not
> needed to handle C callbacks and shouldn't be the *first* thing
> mentioned in a list of alternatives.


A friend, declared extern "C", is the only guaranteed portable means to
implement a C callback in a C++ class.

I guess most people use g++ or other compilers that don't complain about
static members having the wrong linkage, but some do.

--
Ian Collins
  Reply With Quote
Old 06-02-2015, 07:30 PM   #10 (permalink)
Marcel Mueller
Guest
 
Posts: n/a
Default merge C callbacks into C++ class?

On 02.06.15 20.23, Paavo Helde wrote:
> "Note: static member functions do not require an actual object to be
> invoked, so pointers-to-static-member-functions are usually type-
> compatible with regular pointers-to-functions. However, although it
> probably works on most compilers, it actually would have to be an extern
> "C" non-member function to be correct, since “C linkage” doesn’t only
> cover things like name mangling, but also calling conventions, which
> might be different between C and C++."


With IBM VAC++ you cannot use static members with C callbacks since C++
functions /always/ pass the first parameters in registers.

With g++ in contrast it is almost impossible to use -mregparm because it
breaks the runtime library calls. While the public functions like strlen
could be covered by appropriate header files, internal calls, e.g. for
memory allocation of operator new will sadly fail. Not using register
parameters makes the executables unnecessarily large, but you can use
static members a C callbacks.


Marcel
  Reply With Quote
Reply

« Hiding "std" | - »
Thread Tools
Display Modes



All times are GMT. The time now is 11:50 AM.


Powered by vBulletin® Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright ©2010, CodingForum.Org