如何在运行时将任何类型存储在 void* 中?
How to store any type in void* at runtime?
我正在用 C:
编写一个动态数组
struct array {
int len;
int cap;
void *data;
};
如果我知道类型就很容易存储值:
void set(array* a, int idx, int val) {
((int*)a->data)[idx] = val;
}
但我想接受任何类型 (void*):
void set(array* a, int idx, void* val) {
a->data[idx] = val;
}
这显然无法编译,因为 'void' is not assignable
据我了解,编译器需要有关类型的信息来获取其大小并计算偏移量以访问数据。
有什么办法可以自己完成吗?直接对字节进行操作,类似
void set(array* a, int idx, void* val, int size) {
*((char*)a->data + size * idx) = val;
}
基本上我想让它们类似于 Go 切片。您可以在此处阅读有关它们的内置泛型类型的信息:
https://dave.cheney.net/2018/05/29/how-the-go-runtime-implements-maps-efficiently-without-generics
没有模板,没有拆箱。他们使用 void*
进行数据存储。
首先,您需要使用 void* * 数据来存储数组,而不是指向元素的单个指针。
从你所拥有的
[a->data = (void*)val; ] 应该 运行 没问题。
它只是一个指向数据的指针,可以存储为void。当您想要取消引用数据时,您将需要知道如何读取数据。
如果 val 指向一个 int- 为了读取它,您必须强制转换它以让编译器知道要读取多少字节。
所以 : *(int *)(a->data);
我想 memcpy
应该可以满足您的需求:
void set(array* a, int idx, void* val, int size) {
memcpy(a->data + size * idx, val, size);
}
我正在用 C:
编写一个动态数组struct array {
int len;
int cap;
void *data;
};
如果我知道类型就很容易存储值:
void set(array* a, int idx, int val) {
((int*)a->data)[idx] = val;
}
但我想接受任何类型 (void*):
void set(array* a, int idx, void* val) {
a->data[idx] = val;
}
这显然无法编译,因为 'void' is not assignable
据我了解,编译器需要有关类型的信息来获取其大小并计算偏移量以访问数据。
有什么办法可以自己完成吗?直接对字节进行操作,类似
void set(array* a, int idx, void* val, int size) {
*((char*)a->data + size * idx) = val;
}
基本上我想让它们类似于 Go 切片。您可以在此处阅读有关它们的内置泛型类型的信息:
https://dave.cheney.net/2018/05/29/how-the-go-runtime-implements-maps-efficiently-without-generics
没有模板,没有拆箱。他们使用 void*
进行数据存储。
首先,您需要使用 void* * 数据来存储数组,而不是指向元素的单个指针。
从你所拥有的 [a->data = (void*)val; ] 应该 运行 没问题。
它只是一个指向数据的指针,可以存储为void。当您想要取消引用数据时,您将需要知道如何读取数据。
如果 val 指向一个 int- 为了读取它,您必须强制转换它以让编译器知道要读取多少字节。 所以 : *(int *)(a->data);
我想 memcpy
应该可以满足您的需求:
void set(array* a, int idx, void* val, int size) {
memcpy(a->data + size * idx, val, size);
}