То, что вы пытаетесь сделать с первым примером, - это попытка эмулировать наследование от объектно-ориентированных языков.Похоже, вы хотите, чтобы my_struct
имел отношения «есть» с opaque_lib_t
.
Однако это не сработает, потому что тогда вам нужно, чтобы первый член my_struct
был действительным экземпляр структуры opaque_lib_t
, т.е. это должно быть
struct my_struct{
opaque_lib_t opaque_lib_instance; //opaque_lib_t is the opaque type
//came from the library
};
Если opaque_lib_t
действительно является анонимной и непрозрачной структурой, похожей на FILE
, то это невозможно.
Другой взгляд на это выглядит так:
В памяти my_struct
будет выглядеть примерно так:
my_struct opaque_lib_t
+----------------+ +-------------------+
| opaque_lib_ptr | -> | Unknown data |
+----------------+ | More unknown data |
| ... |
+-------------------+
Вы просто не можете наложить opaque_lib_t
поверх my_struct
.
И когда вы делаете return opaque_lib_ptr;
, вы фактически говорите, что «этот указатель указывает на my_struct
, первый член которого является указателем на opaque_lib_t
».И это просто неправильно, потому что это две совершенно разные структуры.
Если продолжить с первого куска кода, если вы попытаетесь использовать my_struct_ptr->opaque_lib_ptr
, то память, к которой вы обращаетесь, является начальными данными структуры opaque_lib_t
.(чей указатель вы вернули).
И наконец о том, что вы говорите
В моем коде я хочу абстрагироваться от конкретных структур библиотеки
Я могу это понять, но это уже цель opaque_lib_t
.Вы добавляете (ненужную) абстракцию поверх абстракции.
Я мог бы понять вашу структуру, если бы она собирала несколько связанных данных, но не только указатель opaque_lib_t
.