I'm writing a library with both a C and C API. I need to write many enums in the C API and wrap them in the C API.
typedef enum PREFIX_SomeType
{
PREFIX_SOME_TYPE_A,
PREFIX_SOME_TYPE_B,
PREFIX_SOME_TYPE_C,
} PREFIX_SomeType;
In the C wrapper header I'd like to have a similar enum without name prefixes, since the C wrapping API uses a namespace called PREFIX.
namespace PREFIX
{
enum SomeType : int
{
SOME_TYPE_A,
SOME_TYPE_B,
SOME_TYPE_C,
};
}
Since these two enums are different enums they don't cleanly convert to one another. Whenever I define a struct in the C api containing enums, I'd like to use a C alias.
typedef struct PREFIX_ApiStruct
{
PREFIX_SomeType type;
// ...
} PREFIX_ApiStruct;
And in the C wrapper:
using namespace PREFIX
{
using ApiStruct = PREFIX_ApiStruct;
}
But, when trying to use the C wrapper we cannot assign a C enum...
ApiStruct instance;
instance.type = SOME_TYPE_A; // Error!
Is there a way to let a C user not write type out PREFIX_ and instead use C namespaces, without requiring explicit casts?
CodePudding user response:
Does an X-MACRO help?
In a shared .h:
#define SOME_TYPE \
X(SOME_TYPE_A) \
X(SOME_TYPE_B) \
X(SOME_TYPE_C)
In the C part:
typedef enum PREFIX_SomeType
{
#define X(type) PREFIX_##type,
SOME_TYPE
#undef X
} PREFIX_SomeType;
In the C part:
namespace PREFIX
{
enum SomeType : int
{
#define X(type) type,
SOME_TYPE
#undef X
};
}
CodePudding user response:
The closest solution I could come up with is using C 17 to do:
inline constexpr PREFIX_SomeType SOME_TYPE_A = PREFIX_SOME_TYPE_A;
inline constexpr PREFIX_SomeType SOME_TYPE_B = PREFIX_SOME_TYPE_B;
inline constexpr PREFIX_SomeType SOME_TYPE_C = PREFIX_SOME_TYPE_C;
This does mess somewhat with syntax highlighting, but I fail to see a better alternative without re-implementing the C struct. This is also easy to generate via x-macro.