Exposing private member functions to extern C function

A

Anonymous

I have a class that needs to be accesed by a C API. I need to expose
some private methods to the C API :


#ifdef __cplusplus
extern "C"
#endif

void peek(Object_Handle handle);
void poke(Object_Handle handle);

#ifdef __cplusplus
}
#endif


class ToBeFlattened
{
public:

//compiler barfs at the next two lines (mangled names?)
//I also cant use the extern C decoration ...
friend __stdcall void peek();
friend __stdcall void poke();

ToBeFlattened();
foo();
bar();

private:
void take_a_peek() const
void poke_all_you_want();
};
 
G

Gianni Mariani

Anonymous said:
I have a class that needs to be accesed by a C API. I need to expose
some private methods to the C API :


#ifdef __cplusplus
extern "C"
#endif

void peek(Object_Handle handle);
void poke(Object_Handle handle);

#ifdef __cplusplus
}
#endif


class ToBeFlattened
{
public:

//compiler barfs at the next two lines (mangled names?)
//I also cant use the extern C decoration ...
friend __stdcall void peek();
friend __stdcall void poke();

__stdcall is not a C++ keyword. You probably don't need it at all.
 
A

AnonMail2005

I have a class that needs to be accesed by a C API. I need to expose
some private methods to the C API :

#ifdef __cplusplus
extern "C"
#endif

void peek(Object_Handle handle);
void poke(Object_Handle handle);

#ifdef __cplusplus}

#endif

class ToBeFlattened
{
public:

//compiler barfs at the next two lines (mangled names?)
//I also cant use the extern C decoration ...
friend __stdcall void peek();
friend __stdcall void poke();

ToBeFlattened();
foo();
bar();

private:
void take_a_peek() const
void poke_all_you_want();



};- Hide quoted text -

- Show quoted text -

You can only let C have access to global functions or static class
functions.
You can't let them have access to member functions - how would C
supply the
instance of the class object that is implicit in the calls to a member
function?
 
J

James Kanze

That should be ``extern "C" {''.

What's Object_Handle?

And this should be two lines (probably got mangled somewhere in
propagation).

There is absolutely no way a C program can ever call these
functions. For several reasons.
You can only let C have access to global functions or static class
functions.

C can only access functions declared ``static "C"''. Global
functions that aren't ``static "C"'' can't be used, nor can
static class functions (which can't be ``static "C"'').
You can't let them have access to member functions - how would
C supply the instance of the class object that is implicit in
the calls to a member function?

That's the most obvious problem. There's also the fact that the
calling conventions may be different between C and C++. The
result is that the "linkage" of a function is part of its type,
and if a function written in C is declared:

extern "C" void f( void (*)() ) ;

then it can only be passed functions declared and defined:

extern "C" void g() {}

In other words, given:

extern "C" {
typedef void (*PtrCFnc)() ;
}
typedef void (*PtrCppFnc)() ;

PtrCFnc and PtrCppFnc are two distinctly different types, with
no implicit conversion from one to the other.
 
I

Ian Collins

James said:
C can only access functions declared ``static "C"''. Global
functions that aren't ``static "C"'' can't be used, nor can
static class functions (which can't be ``static "C"'').
What's `static "C"' That's a new one on me.

I assume you intended to write `extern "C"'.

If you have to call a function with access to a class's private parts
from C, you have to declare it as extern "C" and make it a friend of the
class.
 
J

James Kanze

James Kanze wrote:
What's `static "C"' That's a new one on me.

A typo.
I assume you intended to write `extern "C"'.
Yes.

If you have to call a function with access to a class's
private parts from C, you have to declare it as extern "C" and
make it a friend of the class.

More often, I'll still write it as a member function, and then
write an ``extern "C"'' function which just calls the member
function. In most cases, the function whose pointer is being
passed takes a void* argument, which in fact will be a pointer
to the object, so the actual function being passed will be
something like:

extern "C"
void // Or whatever...
calledFromC( void * p )
{
static_cast< MyClass* >( p )->f() ;
}

The idiom is frequent enough that it would be worth writing a
template for it, except... function templates can't be ``extern
"C"'' either. (Maybe a macro?)
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top