关于contain_of的理解

关于contain_of的理解。
内核中有这样的一个宏:

define container_of(ptr, type, member) ({ \

const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
(type *)( (char *)__mptr - offsetof(type,member) );})

作用是这样的:如果你获得了一个大结构体里面的一个成员的指针,那么通过这个宏,你就能获得这个结构体的指针。

假设存在这么一个结构体:
Struct student{
Type1 A;
Type2 B;
Type3 C;
};
这里的type1,2,3就是我们平时常见的int,char之类的。之所以不写具体的类型是避免还要考虑内存中字节对齐等问题。
现在用这个结构体来声明一个对象:struct student demo;
那么在内存中demo的分布应该是这样的:
—————–0x6000
A
—————- 0x6008
B
—————–0x600a
C
—————-0x600e
上面的内存地址分布都是我随意写的,因为我并没有具体type1.2.3是什么类型。
那么container_of宏的三个参数分别代表什么呢?
Ptr :指向结构体内成员的指针,比如type2 * pointer=&B
Type :这个结构体类型 ,比如 struct student
Member:结构体成员名字,比如 B
代入宏看看是什么样的?

define container_of(pointer, struct student, B) ({ \

const typeof( (( struct student*)0)->B) *__mptr = (pointer);    \
( struct student*)( (char *)__mptr - offsetof( struct student,B) );})

初步的替换就是这样,但是这个里面还有宏offsetof(struct student,B),暂且不看先。
const typeof( (( struct student*)0)->B) *__mptr = (pointer); 这句代码的作用是声明了一个指针__mptr。Typeof的作用是获取变量的类型,所以__mptr的类型就是type2。然后把pointer指针的值赋给它,其实就是两个指针指向同一块内存,就是指向0x6008。
下面展开offsetof( struct student,B) 看看是什么?

define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

替换后得到:

define offsetof(struct student, B) ((size_t) &((struct student*)0)->B)

(struct student*)0)这句话的意思是把student结构体的起始地址强制制定为0,那么B的地址就是相对0地址的偏移量,然后取址,在上图中就是0x0008.
回看(char )__mptr这句话的意思:把这个指针强制类型转换为(char),也就是这个指针现在是字节指针了。为什么这么做呢?因为内存存储的最基本单位都是字节。这样的转换可以用来做加减法十分方便。
综上所述,0x6008-0x0008=0x6000.这个地址也就是demo结构体的起始地址了,然后转换为struct student类型的指针。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误是因为在函数 "cv::collectCalibrationData" 中,参数 "objectPoints" 应该是一个由向量组成的向量,每个向量都包含 "Point3f" 型的点。您可以检查一下您的代码,看看是不是在调用该函数时,将 "objectPoints" 参数传递为了一个错误类型或格式的变量。如果您仍然无法解决问题,请提供更多的上下文信息,以便我更好地帮助您解决问题。 ### 回答2: 在函数'cv::collectCalibrationData'中,参数objectPoints应该是一个Point3f类型的点的向量的向量(vector of vectors)。具体来说,objectPoints是一个存储了多个平面点集的容器,每个平面点集都是一个Point3f类型的点的向量。 Point3f是OpenCV中定义的一种数据类型,它表示一个三维点,包含了三个浮点类型的坐标值,分别表示该点在三维空间中的x、y、z坐标。因此,objectPoints向量的每个元素都是一个平面点集,其中的每个元素都表示了一个三维点。 为了更好地理解objectPoints,可以将其想象为一个矩阵,每一行表示一个平面点集,每一列表示一个三维点的坐标。通过使用objectPoints参数,在函数'cv::collectCalibrationData'中可以传递多个平面点集的信息,便于在后续的摄像机标定过程中使用这些点集进行计算和优化。 通过使用objectPoints参数,函数'cv::collectCalibrationData'可以收集并整理多个平面点集的信息,为后续的摄像机标定提供准确的输入数据。这样的设计为用户提供了更灵活和高效的方式来处理多组平面点集,满足了不同应用场景下对于摄像机标定数据的需求。 ### 回答3: 在OpenCV中,函数'cv::collectCalibrationData'中的objectPoints参数应包含Point3f类型的点的向量的向量。 Point3f是OpenCV中的一个类,用于表示三维空间中的点。其包含三个成员变量:x,y和z,分别表示点在三个坐标轴上的坐标。 在函数'cv::collectCalibrationData'中,objectPoints参数是用于存储标定对象的三维点信息的。标定对象通常是一个具有已知大小和形状的物体,通过对其进行图像采集和分析,可以推断出相机的内外参数,从而实现摄像机的准确定位。 objectPoints应该是一个向量的向量,其中每个子向量包含若干个Point3f类型的点。这样可以存储多个标定对象的信息,每个标定对象由多个三维点组成。 举个例子,如果我们要标定一个棋盘格模板,棋盘格上每个交叉点可以看作是一个三维点。我们可以在objectPoints中存储多个棋盘格的三维点信息,每个棋盘格由若干个三维点组成的向量表示。 在函数'cv::collectCalibrationData'中,当我们调用该函数时,需要传入objectPoints参数并填充数据。在使用标定函数进行相机标定之前,我们需要提前收集好标定对象的三维点信息,并将其存储在objectPoints中,以便函数可以使用这些数据进行标定。 总结而言,函数'cv::collectCalibrationData'中的objectPoints参数是用于存储标定对象的三维点信息的向量的向量,每个子向量包含Point3f类型的点,用于实现相机的准确定位和标定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值