how do you write a c wrapper for a c++ class with inheritance
Asked Answered
A

1

6

I was just wondering if there was a way to create a c wrapper API for a c++ class that has inheritance.

Consider the following:

class sampleClass1 : public sampleClass{

  public:
    int get() { return this.data *2; };
    void set(int data);
}


class sampleClass : public sample{

  public:
   int get() { return this.data; }
   void set(int data) {this.data = data; }
}

class sample {

 public:
   virtual int get();
   virtual void set(int data);

 private:
   int data;

}

How would I wrap the sampleClass1 to make it work in a c context ???

thanks,

Anneliese answered 31/10, 2014 at 19:52 Comment(3)
please define "to make it work in a c context?" what are you trying to do?Pinot
I mean for instance accessing the sampleClass.data member within a c context. Or accessing a sampleClass member from a sampleClass1 object within a c context.Anneliese
What do you mean by "c context"? Do you want to call this code from C programming language?Tangram
D
5

First, your sample should really get a proper virtual dtor.

Next, just add one free function with C-binding for each function which is part of the interface, simply delegating:

"sample.h"

#ifdef __cplusplus
extern "C" {
#endif
typedef struct sample sample;
sample* sample_create();
sample* sample_create0();
sample* sample_create1();
void sample_destroy(sample*);
int sample_get(sample*);
void sample_set(sample*, int);
#ifdef __cplusplus
}
#endif

"sample-c.cpp"

#include "sample.h" // Included first to find errors
#include "sample.hpp" // complete the types and get the public interface

sample* sample_create() {return new sample;}
sample* sample_create0() {return new sampleClass;}
sample* sample_create1() {return new sampleClass1;}
void sample_destroy(sample* p) {delete p;}
int sample_get(sample* p) {return p->get();}
void sample_set(sample* p, int x) {p->set(x);

"sample.hpp"

// Your C++ header here, with class definition

"sample.cpp"

#include "sample.hpp" // Included first to find errors
// Implement the class here
Drupe answered 31/10, 2014 at 20:1 Comment(6)
Hmmm, thought just of s.th. alike, but the inheritance factor makes up the interesting part of the question, especially as vtables are involved. I'd say for a c interface the basic structhandle should provide some discriminator field.Haldis
Do i have to do this for every class that inherits the sample class if i need to access the top level class object?Anneliese
You only have to create such C-linkage forwarders for those members you are interested in (Also, you might want to use a later class as the least-derived class the handle corresponds to). And perhaps you would want to have only one create-function, with arguments.Drupe
@πάνταῥεῖ: Why a discriminator? We are delegating all the work of being discriminatory to the C++ side here.Drupe
Would I have to type cast the top level object to the lower levels in order to access the inherited type?Anneliese
Yes, you would have to do so, wherever you know (and must acknowledge) that you are actually that you actually have a derived. In this example, that's nowhere though.Drupe

© 2022 - 2024 — McMap. All rights reserved.