I have a shared library written in C++ that i need to expose for C as well.
Let's say i have to wrap the following class :
class Foo
{
public:
const std::vector<int> &getList() const
{
return m_list;
}
private:
std::vector<int> m_list {0, 1, 2, 3, 4};
};
First wrapper version :
struct wrap_foo
{
Foo m_f;
};
typedef struct wrap_foo *wrap_foo_t;
const int *getList(wrap_foo_t f) // useful ?
{
return f->m_f.getList().data();
}
int listSize(wrap_foo_t f)
{
return f->m_f.getList().size();
}
int getVal(wrap_foo_t f, int i)
{
return f->m_f.getList().at(i);
}
wrap_foo_t createFoo()
{
return new wrap_foo;
}
void cleanFoo(wrap_foo_t f)
{
delete f;
}
2nd wrapper version :
struct vec
{
const int *first;
int size; // number of elements
};
typedef struct vec *vec_t;
vec_t getList2(wrap_foo_t f)
{
vec_t v = new vec;
v->first = f->m_f.getList().data();
v->size = f->m_f.getList().size();
return v;
}
int getVal2(vec_t v, int i)
{
return *(v->first + i);
}
void cleanVec(vec_t v)
{
delete v;
}
For the first version, the C client code would then use the C API in this way :
wrap_foo_t wf = createFoo();
for (int i = 0; i < listSize(wf); i++)
printf("v = %d\n", getVal(wf, i));
cleanFoo(wf);
And in the 2nd version :
wrap_foo_t wf2 = createFoo();
vec_t list = getList2(wf2);
for (int i = 0; i < list->size; i++)
printf("v = %d\n", getVal2(list, i));
cleanVec(list);
cleanFoo(wf2);
The internal list is wrapped into a c structure in the second version, keeping its size. In the first version, each time the class is extended (for example by adding other getList methods, getList1, getList2,..), 2 wrappers functions are needed (one to return a pointer, one to return the size).
Is there a better choice to wrap this class ? (except from errors that are not handled in this small example here)
Thank you.