1 year ago
#383826
glades
Get class member from next member's address
I'm wrapping a C interface and require to pass into it the address of a preallocated buffer. My wrapper places this buffer at a known location within wrapper object A
. At runtime, I will be able to query the API for its buffer address. I need to be able to somehow get the wrapper object address however. Now this is what I've come up with:
- This is a simplified testcase:
std::array buf_
represents the buffer I'm passing into the C function. - The function
glean_ptr()
simulates the behavior of the API: it returns the pointer to the buffer. - I then want to be able to determine the address of the wrapping object
A
from the buffer address -> I packed it in a substruct and decrease its address.
#include <iostream>
#include <array>
struct A
{
A() : obj_{this} {}
#pragma pack(1)
struct B {
A* self_;
std::array<int, 10> buf_;
} obj_;
auto glean_ptr() { return &obj_.buf_; }
void say_hello() { std::cout << "hello" << std::endl; }
};
int main()
{
A a;
auto ptr = a.glean_ptr();
// do some hacking
A* b = reinterpret_cast<A*>(ptr)-1;
b->say_hello();
}
I have two questions:
- Will this always work? It works in the DEMO, but I'm planning to use it on a microcontroller (32 bit registers).
- The compiler is not able to see through this I think. Might there a better way to achieve the same result without ugly
reinterpret_cast
?
EDIT according to @François Andrieux's suggestions (only array pointer arithmetics is defined in C++ standard):
#include <iostream>
#include <array>
struct TCB_ // struct of which the C API returns a handle to
{
int a;
int b;
char c;
long long d;
};
struct A
{
A() : buf_{this} {}
static constexpr size_t S_ = (1+sizeof(TCB_)/sizeof(A*) + !!(sizeof(TCB_)%sizeof(A*)));
std::array<A*, S_> buf_;
TCB_* glean_ptr() { return reinterpret_cast<TCB_*>(&buf_[1]); }
void say_hello() { std::cout << "hello" << std::endl; }
};
int main()
{
A a;
auto ptr = a.glean_ptr();
// do some hacking
A* b = reinterpret_cast<A*>(ptr)-1;
b->say_hello();
}
c++
c++17
wrapper
reinterpret-cast
class-members
0 Answers
Your Answer