• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

200
Vistas
Implementing a C++ (pure) interface using plain C

Given a pure C++ class:

class ICppA {
public:
    virtual ~ICppA() {}
    virtual double add(double v) = 0;
    virtual double sub(double v) = 0;
    virtual double get() = 0;
};

Are there ways to create implementations of this interface in plain C in clang and gcc?

I understand the C++ standard does not cover the vtable structure, and I understand this may not be a good idea. I am looking for compiler specific, probably non-portable solutions.

Example for MSVC

The following works for MSVC, (but is not portable):

typedef struct CA CA;

// The plain C vtable
struct CA_VTable {
    void (*dtor)(CA*);
    double (*add)(CA*, double v);
    double (*sub)(CA*, double v);
    double (*get)(CA*);
};

// The plain C implementation
struct CA {
    CA_VTable* _vtable;
    double total;
};

void CA_DTor(CA*) {}
double CA_Add(CA* o, double v) { return (o->total += v); }
double CA_Sub(CA* o, double v) { return (o->total -= v); }
double CA_Get(CA* o) { return o->total; }

// Create a static vtable that all instances can use
static CA_VTable _CA_VTable = {
    CA_DTor,
    CA_Add,
    CA_Sub,
    CA_Get
};

void CA_CTor(CA* ca) { ca->_vtable = &_CA_VTable; ca->total = 0; }
void testA(ICppA* a)
{
    std::cout << "initial value: " << a->get() << std::endl;
    std::cout << "add 5: " << a->add(5) << std::endl;
    std::cout << "sub 2: " << a->sub(2) << std::endl;
}

int main()
{
    CA ca;
    CA_CTor(&ca);
    testA((ICppA*)&ca);
    CA_DTor(&ca);
    return 0;
}

[EDIT] It seems like the code above will work on clang and gcc if the vtable contains an extra pointer before the first method, i.e.

// The plain C vtable
struct CA_VTable {
    void* unknown;
    void (*dtor)(CA* self);
    double (*add)(CA* self, double v);
    double (*sub)(CA* self, double v);
    double (*get)(CA* self);
};

[...]

// Create a static vtable that all instances can use
static CA_VTable _CA_VTable = {
    nullptr,
    CA_DTor,
    CA_Add,
    CA_Sub,
    CA_Get
};

(I am still reading to figure out what that unknown pointer is and if the solution then becomes reliable)

about 3 years ago · Santiago Trujillo
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda