I'm writing a program that generates C (technically a superset of C) wrappers for C++ code. If the input is something like:
class c {
class priv{};
public:
typedef priv mytypedef; // Provides a way to construct priv
static priv myfactory() {priv ret; return ret;} // Provides another way to construct priv
};
The generated wrappers look like this:
template <typename T>
auto destruct_or_throw(T* t) -> decltype(t->~T()) {
t->~T();
}
auto destruct_or_throw(void*) -> void {
std::abort();
}
void *c_mytypedef_wrapper() {
auto ptr = (c::mytypedef *)malloc(123); // In my usecase, I know the size of the priv class
c::mytypedef val;
*ptr = val;
return ptr;
}
void *c_myfactory_wrapper() {
auto ptr = (decltype(c::myfactory()) *) malloc(123); // In my usecase, I know the size of the priv class
auto val = c::myfactory();
*ptr = val;
return ptr;
}
void c_callable_destruct(void* t) {
// destruct_or_throw((c::priv *) t); // compile error, because priv is private
destruct_or_throw((decltype(c::myfactory()) *) t); // would work, but relies on us having the string "myfactory" when codegenerating this
destruct_or_throw((c::mytypedef *) t); // would work, but relies on us having the string "mytypedef" when codegenerating this
free(t);
}
int main() { // example use
auto val1 = c_mytypedef_wrapper();
c_callable_destruct(val1);
auto val2 = c_myfactory_wrapper();
c_callable_destruct(val2);
}
The hard part is destructing a priv object in c_callable_destruct
.
If the program that codegens the wrappers had either the string "mytypedef" or "myfactory" then I could use
destruct_or_throw((decltype(c::myfactory()) *) t);
or
destruct_or_throw((c::mytypedef *) t);
to destruct it. If priv
would not be private, then I could use
destruct_or_throw((c::priv *) t);
to destruct it. Unfortunately priv is private and when my program codegens c_callable_destruct
there is no easy way to get the strings "mytypedef" or "myfactory". Any idea how to destruct this object?
Edit: My old question was worded poorly: This was the old phrasing:
Lets say I have a privately declared class priv
:
class c {
class priv{};
};
This means that the following code
void priv_arg(c::priv* ptr) {...}
won't compile. Is it possible to make the code below compile? I need to write a function that takes a pointer to a c::priv (or any other type with an identical layout) as an argument and I cannot touch the c
class.
I know that you can access private member variables (https://github.com/martong/access_private), but I don't know how to access private types.