Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping C++ references into a C API

Tags:

c++

c

reference

I have a header file for what is supposed to be a combined C++ and C API. The C part is wrapped into extern "C", but the declarations themselves look very much unlike C; for example:

foo::Bar& Foo_Baz_GetBarOfQux(void *_self, const foo::Qux &qux);

Is there a way to actually use it form plain C? I obviously cannot use this header, but maybe I can redeclare it somehow:

/* type? */ Foo_Baz_GetBarOfQux(void*, const /* type? */);

What puzzles me is how to declare types of these references (if it's possible).

P.S. I know I can write my own C wrapper on top of this: I declare the classes as opaque structures:

typedef struct foo_bar foo_bar_t;
typedef struct foo_baz foo_baz_t;
typedef struct foo_qux foo_qux_t;

and then write a C-like function that wraps the above function:

extern "C" 
foo_bar_t*
foo_baz_get_bar_of_qux(
    foo_baz_t* baz,
    foo_qux_t* qux)
{
    return (foo_bar_t*) Foo_Baz_GetBarOfQux(baz, *(foo::Qux*)qux);
}

But I wonder if I can use the original Foo_Baz_GetBarOfQux() directly.

like image 947
Mikhail Edoshin Avatar asked Jan 18 '23 17:01

Mikhail Edoshin


2 Answers

No you cannot use Foo_Baz_GetBar() directly, the calls to a member function in c++ involves implicitly passing of an this pointer which does not exist in your c code.

like image 146
Alok Save Avatar answered Jan 25 '23 07:01

Alok Save


In general, it would be better to use opaque structures.

In the "C" interface of the code, do not ever try to pry within the opaque structure, just dutifully pass the pointers around.

In the "C++" part, you should define the structure and actually fill them appropriately (I would avoid the blind typecasting).

Of course, the "C++" part should not be exposed in the "C" header lest it confuses the C compiler.

like image 20
Matthieu M. Avatar answered Jan 25 '23 07:01

Matthieu M.