1

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.

Volker Weißmann
  • 554
  • 1
  • 6
  • 24

0 Answers0