For a type to be opaque means you can't look inside it: it's a "black box" that can be passed around but not inspected or manipulated directly by the C code. You typically refer to the object using either heap-allocated memory and void*s, or using functions to determine the necessary length and buffers.
For example, a C++ object might contain a std::string
, but the layout of a std::string
is not specified in the C++ Standard, so you can't write C code that directly reads from or writes to the string (at least, not without having a total understanding of the std::string
layout, manually revalidated every time the compiler/STL is updated).
So, to allow C code to access the object, you might write C-callable functions such as:
#if __cplusplus
extern "C" {
#endif
void* object_new();
const char* object_get_string(void* p_object);
void object_set_string(void* p_object, const char* s);
void object_delete();
#if _cplusplus
}
#endif
With C++ implementation ala:
class Object { std::string string_; ... }
void* object_new() { return new Object; }
const char* object_get_string(void* p) { return ((Object*)p)->string_.c_str()); }
...
Here, the object_XXX functions provide the C code with a safe way to use the Object.