C++ offsetof

这是一个宏,用于计算类中某个成员的地址相对于类实例的偏移量

在C++11中,要求这个类standard_layout

基本用法是这样子的:

#include <stdio.h>      /* printf */
#include <stddef.h>     /* offsetof */

struct foo {
    char a;
    char b[10];
    char c;
};

int main ()
{
    printf ("offsetof(struct foo,a) is %d\n",(int)offsetof(struct foo,a));
    printf ("offsetof(struct foo,b) is %d\n",(int)offsetof(struct foo,b));
    printf ("offsetof(struct foo,c) is %d\n",(int)offsetof(struct foo,c));

    printf("%d\n", &(((struct foo*)0)->c));
    
    return 0;
}

注意除了用offsetof宏之外, printf("%d\n", &(((struct foo*)0)->c));也是一种办法

求取某个特定成员的偏移量的意义在哪儿呢?

linux内核中对于这一特性有一个绝佳的应用。内核数据结构中用到了很多的双向链表,进程描述符、页面描述符等等,它们各自被定义成不同

的结构体类型,但就双向链表这一数据结构而言,操作却是完全一致的,听起来该是c++模板大显身手的地方了。

于是就想到定义这样一种链表节点:

struct list_head
{
    struct list_head *next, *prev;
};

需要使用双向链表的类型就会含有这样的成员,比如:

typedef struct page
{
    struct list_head list;
    .....
    struct page *next_hash;
   .....
    struct list_head lru;
}mem_map_t;

这里面的成员(list或者lru)都会与其它page结构体中对应的链表节点成员相连,相当于成为一个连接件。

问题是我们要的是两个page结构之间相连,你弄成它们的成员相连,怎么用呢??

这就是offsetof大显身手的时候了,有了它,我们在知道成员地址之后,能求出page实例的基地址,从而

变相的实现了将两个page连接在一起的目的,同时复用了双链表这一基本数据结构。

转载于:https://www.cnblogs.com/hustxujinkang/p/5034204.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 OpenGL 中绘制网格,需要使用顶点缓冲对象(VBO)和索引缓冲对象(IBO)来存储顶点和面的数据。以下是一个简单的示例: 首先,定义一个顶点结构体和一个顶点数组: ``` struct Vertex { glm::vec3 position; glm::vec3 color; }; std::vector<Vertex> vertices; ``` 然后,创建一个 VBO 并将顶点数据绑定到它上面: ``` GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); ``` 接下来,定义一个索引数组来存储网格面的顶点索引: ``` std::vector<GLuint> indices; ``` 将索引数据绑定到 IBO 上: ``` GLuint ibo; glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW); ``` 最后,绘制网格: ``` glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, color)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); ``` 在上述代码中,我们首先启用顶点属性,并将位置和颜色属性绑定到顶点数组上。然后绑定 IBO,并使用 glDrawElements 函数绘制网格。最后禁用顶点属性。 这是一个简单的示例,实际应用中还需要考虑更多的细节,比如顶点法线、纹理坐标等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值