У меня есть устаревший C -API, который обеспечивает обратные вызовы для асинхронных операций. Так как эта библиотека требует много флагов компилятора, полна макросов и заголовок генерирует тонны предупреждений при включении, я решил создать оболочку для этой библиотеки, которая инкапсулирует проприетарную C -библиотеку.
Но так как это Библиотека является асинхронной, она предоставляет функции обратного вызова. Проблема в том, что для обратного вызова требуется указатель на структуру (X_leg
). Но так как эта структура является частью старого API, и я не хочу включать структуру, я решил создать структуру с тем же макетом X_wrp
. В main () я гарантирую, что размер обеих структур равен.
Мой вопрос сейчас: Безопасно ли reinterpret_cast
указатель функции-оболочки типа func_wrp
на указатель устаревшей функции с типом func_leg
? Или это неопределенное поведение в C ++ 17?
У меня есть следующий минимальный рабочий пример:
#include <iostream>
#include <cstdint>
//begin of wrapper decls
struct X_wrp {
std::uint32_t member;
};
using func_wrp = void (*)(const X_wrp* arg);
void caller_wrp(func_wrp func);
//end of wrapper decls
//Legacy C-Code
typedef struct {
std::uint32_t member;
} X_leg;
typedef void (*func_leg)(const X_leg* arg);
void caller_leg(func_leg func) {
static X_leg inst{10};
func(&inst);
}
//End of Legacy C-Code
void callback(const X_wrp* arg) {
std::cout << arg->member << std::endl;
}
int main() {
static_assert(sizeof(X_leg)==sizeof(X_wrp));//ensures that there is no oops
caller_wrp(callback);
return EXIT_SUCCESS;
}
//begin of wrapper implementations
void caller_wrp(func_wrp func) {
caller_leg(reinterpret_cast<func_leg>(func)); //is this cast safe?
}
//end of wrapper implementations