0

I have a C++ API that is exposed to other languages via C API. Suppose there is this C struct the array of which needs to be exposed via C API.

struct SomeCStruct {
   // C compatible types
   int i;
   bool b;
...
}

In C++ world it has associated C++ objects, so one way of storing this would be:

class SomeCppClass {
   SomeCStruct cStruct;
   
   // Associated C++ objects that can not be exposed via C API
   std::string s; // 'std::string' for example could be any other non C compatible type
}

The problem with this is that although it would be possible expose C array pointer SomeCStruct* it would require pointer arithmetic in client language to correctly jump to the next element. This is not acceptable.

Alternative would be to decouple C and C++ data into different arrays (thus C array can be accessed as usual) and come up with a mechanism to associate them, however this is the last option I will go for.

Another idea I had is having this C struct and casting __associatedData to 'std::string' on C++ side.

struct SomeCStruct {
   // C compatible types
   int i;
   bool b;
   char __associatedData[8]; // !!! Assuming sizeof(std::string) is equal to 8 bytes
}

I hoped to create an extern variable assign sizeof(std::string) to it in C++ translation unit and use as the size of __associatedData, however variable length array in structure is not supported in C. So this is not platform independent, also probably there could be memory alignment inconsistencies.

Is there a proper trick to keep the data in one struct while also having it exposed as a C API?

user1668604
  • 431
  • 2
  • 11
  • 1
    How about a *pointer* to the `SomeCppClass`, using `void *` in C? Then the C-compatible API (implemented in C++) uses that pointer to cast into the correct `SomeCppClass` pointer. – Some programmer dude Oct 15 '22 at 11:32
  • 1
    Also, what is the actual relationship between `SomeCStruct` and `SomeCppClass`? Perhaps `SomeCppClass` should *inherit* from `SomeCStruct`? Then any pointer to a `SomeCppClass` object will also be a pointer to `SomeCStruct` because of the is-a relationship of inheritance. Then the C++ implementation takes a `SomeCStruct` pointer as argument, and *downcast* it to a `SomeCppClass` pointer. – Some programmer dude Oct 15 '22 at 11:34
  • If you want arrays then I think it is not possible in a standard compliant way. If you want an array, then an array of pointer might be the good solution. – Phil1970 Oct 15 '22 at 13:08

0 Answers0