Does this make sense? Calling C++ inside extern "C" block

T

terrencel

I was told to look at some old C code that was ported to C++.

One of the file is like:

=========================================

CPPClass* someCPPVar = NULL;

extern "C"
{

void init()
{
someCPPVar = new CPPClass();
}

void somefunction()
{
bool (*callback)(...);
callback = NULL;

someCPPVar->someMethod((void (**)(...))&callback);

}
}

=========================================

My questions:
1. Can I remove the 'extern "C"' block as I have the source code?
I can just use a C++ compiler to compile it. Right?

2. Currently, I got compile error as follows: (Sun Forte Developer 7 C++ 5.4)

Error: Formal argument 1 of type void(*)(...)* in call to
CPPClass::someMethod(void(*)(...)*) is being passed extern
"C" void(*)(...)*.

Does anyone know how to resolve this problem?

Thanks in advance
 
D

David Lindauer

I was told to look at some old C code that was ported to C++.

One of the file is like:

=========================================

CPPClass* someCPPVar = NULL;

extern "C"
{

void init()
{
someCPPVar = new CPPClass();
}

void somefunction()
{
bool (*callback)(...);
callback = NULL;

someCPPVar->someMethod((void (**)(...))&callback);

}
}

this is typical 'thunk' code so that a C language module (or sometimes assembly
language) can indirectly
invoke a C++ class member function. It is sometimes used in embedded systems to
attach 'interrupts' to C++ member functions, but is also used to form a bridge
between C language modules and C++ language modules.

Mote that the 'extern "C"' does NOT say you can't use C++ code, what it says is
that the name mangling for the functions in its scope is going to conform to C
language usage rather than C++ language usage. What that implies indirectly is
that you can't have overloaded functions using the extern "C" linkage but that if
you have C language modules they can find the functions.

If you remove the extern "C" you may run into link errors down the road... but
that really depends on whether this code is still active or whether the original
reason it was written is obsoleted by further enhancements to the code (e.g. did
they go even further in turning this into native C++ code).

As far as the other issue you are seeing, it looks like the 'callback' variable
is being declared with extern "C" linkage but that since the class declaration
was done with C++ linkage there is a mismatch in the
linkage types. I'm not sure how to fix it... I'm not sure if I've seen a
compiler care as long as you don't
blatantly start assigning non-static class member functions to such variables...
I would say use 'cdecl' in the member function argument declaration but I'm not
100% sure that will fix it... or even if that is something that is part of the
standard and will be in your compiler. Another possibility is to move the
'callback' variable outside the 'extern "C"' block (make it global) but it
depends on exactly how much of this patch code there is to change... and *that*
may be an issue if the callbacks the code is trying to pass really do have C
language linkage... another thing that *may* work is to remove the global nature
of the extern "C" block and just qualify the individual functions as extern
"C"... one other idea is to put another level of thunking in, have the extern
"C" functions directly call C++ functions which declare the variables and do the
thunking up to the class methods.

Maybe someone else here will have other ideas or be able to tell you explicitly
what your compiler will accept.

David







Error: Formal argument 1 of type void(*)(...)* in call to
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top