C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 32:
[32.8] How can I pass an object of a C++ class to/from a C function?

Here's an example (for info on extern "C", see the previous two FAQs).

Fred.h:

/* This header can be read by both C and C++ compilers */
#ifndef FRED_H
#define FRED_H

#ifdef __cplusplus
  class Fred {
  public:
    Fred();
    void wilma(int);
  private:
    int a_;
  };
#else
  typedef
    struct Fred
      Fred;
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if defined(__STDC__) || defined(__cplusplus)
  extern void c_function(Fred*);   /* ANSI C prototypes */
  extern Fred* cplusplus_callback_function(Fred*);
#else
  extern void c_function();        /* K&R style */
  extern Fred* cplusplus_callback_function();
#endif

#ifdef __cplusplus
}
#endif

#endif /*FRED_H*/
Fred.cpp:
// This is C++ code

#include "Fred.h"

Fred::Fred() : a_(0) { }

void Fred::wilma(int a) { }

Fred* cplusplus_callback_function(Fred* fred)
{
  fred->wilma(123);
  return fred;
}
main.cpp:
// This is C++ code

#include "Fred.h"

int main()
{
  Fred fred;
  c_function(&fred);
  ...
}
c-function.c:
/* This is C code */

#include "Fred.h"

void c_function(Fred* fred)
{
  cplusplus_callback_function(fred);
}
Unlike your C++ code, your C code will not be able to tell that two pointers point at the same object unless the pointers are exactly the same type. For example, in C++ it is easy to check if a Derived* called dp points to the same object as is pointed to by a Base* called bp: just say if (dp == bp) .... The C++ compiler automatically converts both pointers to the same type, in this case to Base*, then compares them. Depending on the C++ compiler's implementation details, this conversion sometimes changes the bits of a pointer's value.

(Technical aside: Most C++ compilers use a binary object layout that causes this conversion to happen with multiple inheritance and/or virtual inheritance. However the C++ language does not impose that object layout so in principle a conversion could also happen even with non-virtual single inheritance.)

The point is simple: your C compiler will not know how to do that pointer conversion, so the conversion from Derived* to Base*, for example, must take place in code compiled with a C++ compiler, not in code compiled with a C compiler.

NOTE: you must be especially careful when converting both to void* since that conversion will not allow either the C or C++ compiler to do the proper pointer adjustments! The comparison (x == y) might be false even if (b == d) is true:

void f(Base* b, Derived* d)
{
  if (b == d) {   Good Validly compares a Base* to a Derived*
    ...
  }

  void* x = b;
  void* y = d;
  if (x == y) {   Bad BAD FORM! DO NOT DO THIS!
    ...
  }
}
As stated above, the above pointer conversions will typically happen with multiple and/or virtual inheritance, but please do not look at that as an exhaustive list of the only times when the pointer conversions will happen.

You have been warned.

If you really want to use void* pointers, here is the safe way to do it:

void f(Base* b, Derived* d)
{
  void* x = b;
  void* y = static_cast<Base*>(d);   If conversion is needed, it will happen in the static_cast<>
  if (x == y) {   Good Validly compares a Base* to a Derived*
    ...
  }
}