我使用了一些声明了一些不透明类型的库。我将这种类型包装到我自己的结构中以抽象出这个库不透明类型并遇到了一些问题。这是代码:
typedef struct my_struct my_struct;
struct my_struct{
opaque_lib_t *const opaque_lib_ptr; //opaque_lib_t is the opaque type
//came from the library
};
my_struct* initialize(){
opaque_lib_t *opaque_lib_ptr;
init(&opaque_lib_ptr); //library function call
return opaque_lib_ptr;
}
void use_and_release(my_struct *my_struct_ptr){
//use and release my_struct
}
my_struct *my_struct_ptr = initialize();
use_and_release(my_struct_ptr); //crashes
在这样的实现中,对 use_and_release
的调用会崩溃。所以我尝试用以下实现替换 my_struct* initialize
my_struct* initialize(){
opaque_lib_t *opaque_lib_ptr;
init(&opaque_lib_ptr);
my_struct *my_struct_ptr = malloc(sizeof(*my_struct_ptr));
my_struct tmp = {.opaque_lib_ptr = opaque_lib_ptr};
memcpy(my_struct_ptr, &tmp, sizeof(tmp));
return my_struct_ptr;
}
有了这样的实现,它工作正常。但我不明白为什么第一个不起作用。我认为指向结构的指针和指向其第一个元素的指针具有相同的值。因此,在这种情况下,返回 opaque_lib_t*
并将其转换为 my_struct*
应该没问题,因为 my_struct*
仅包含一个元素。
最佳答案
您尝试使用第一个示例的原因是试图模拟面向对象语言的继承。看来你想要my_struct
与 opaque_lib_t
有"is"关系.
但是那是行不通的,因为那时您需要 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
really 是一个类似于 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
的初始数据结构(你返回了它的指针)。
最后关于你说的话
In my code I want to abstract over the specific library structures
我能理解,但这已经是opaque_lib_t
的目的了。 .您在抽象之上添加了(不必要的)抽象。
如果它收集了多个相关数据,我就能理解你的结构,而不仅仅是opaque_lib_t
指针。
关于c - 从函数返回指向结构的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53606961/