假设我有一个Base有N孩子的班级Derived0, Derived1, ... ,DerivedN.我正在尝试为继承的对象创建池分配器Base,并且实现依赖于知道最大子节点的大小Base,因为每个池都足够大以包含其中一个对象.这是一个简单的例子,包含琐碎的类和N = 2.实际上,N可能更大,而且Base孩子可能不是简单的POD课程.
class Base {
public:
virtual ~Base() = 0;
};
class Derived0 : public Base {
int a;
};
class Derived1 : public Base {
int a, b;
};
class Derived2 : public Base {
int a, b, c;
};
Run Code Online (Sandbox Code Playgroud)
所以我想说我想创建一个足够大的缓冲区来存储10个孩子.我一直在敲打这个问题一段时间,这就是我能想到的:
static const size_t NUMBER_OF_POOLS = 10;
static const size_t LARGEST_CHILD_SIZE =
sizeof(Derived0) > sizeof(Derived1) ?
sizeof(Derived0) > sizeof(Derived2) …Run Code Online (Sandbox Code Playgroud) 据我所知,ioctl()用于向用户空间应用程序公开"扩展"系统调用接口.而不是添加数千个特定驱动程序独有的系统调用,ioctl()用于通过单个系统调用提供可扩展的驱动程序特定功能.
这看起来很清楚.但是,我正在尝试编译我的第一个使用ioctl()呼叫的应用程序,我开始怀疑我的理解.
具体来说,我想ioctl()打电话给"消毒"eMMC设备.看一下/usr/include/linux/mmc/ioctl.h(或者在内核源代码中include/uapi/linux/mmc/ioctl.h),我可以看到这个结构:
struct mmc_ioc_cmd {
// Most fields omitted
int write_flag;
__u32 opcode;
__u32 arg;
};
Run Code Online (Sandbox Code Playgroud)
从用户空间,我没有任何问题,包括这个标题,并将此结构传递给我的ioctl()调用.
所以这就是我的最终消毒片段:
int sanitize(int fd)
{
struct mmc_ioc_cmd command;
memset(&command, 0, sizeof(command));
command.write_flag = 1;
command.opcode = MMC_SWITCH;
command.arg = EXT_CSD_SANITIZE_START << 16;
return ioctl(fd, MMC_IOC_CMD, &command);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,MMC_SWITCH并且EXT_CSD_SANITIZE_START都在内核头文件中定义.具体来说,在我的内核源代码中,它们都被发现了include/linux/mmc/mmc.h.
我在互联网上看到的一切都说在构建用户空间项目时不包含来自内核源代码的头文件.如果是这样的话,你怎么能合理地使用MMC ioctl()?内核公开了要传入的结构ioctl(),但似乎只能通过在内核源代码中隐藏的"隐藏"常量填充它来使用该结构.
我目前的解决方案是将必要的常量从内核头文件复制到我自己的项目中,但这对我来说很脏.
我误解了用例ioctl()吗?这是设计疏忽吗?
鉴于:
boost::variant<T1,T2,T3,...,TN>
Run Code Online (Sandbox Code Playgroud)
在编译时计算以下内容:
max(sizeof(T1), sizeof(T2), sizeof(T3),... ,sizeof(TN))
Run Code Online (Sandbox Code Playgroud)
我不知道如何处理这个,但这个答案揭示了我如何开始.使用两个类型的答案中的代码,T1并且T2,我可以在源文件中使用以下内容来获取更大对象的大小:
size_t largestSize = sizeof(largest<T1, T2>::type);
Run Code Online (Sandbox Code Playgroud)
这正是我想要做的,但我需要largest模板来处理两个以上的类 - 具体来说,它需要检查存储在boost::variant对象中的所有类型.
我知道boost::variant有一个typestypedef,它定义了变体中某种类型的列表.问题是,当我试图绕过实现中的所有boost::mpl内容时,我完全迷失了.我不直观地了解什么boost::variant::types 是的,我如何能够将它传递到我自己的模板做了它.
在我看来,这是最终实现的样子:
typedef boost::variant<T1, T2, T3, T4> MyVariant;
size_t largestSize = sizeof(largest<MyVariant::types>::type);
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不知道如何实现这个版本largest.
我不确定这是否是一种合理的方法,所以我愿意接受任何其他方法来实现这一点(可能boost::static_visitor在编译时应用于所有类型?).
我正在使用 Xilinx Zynq-7000 SoC,并尝试从“传统”(uImage + DTB + initramfs 映像)过渡到“现代”(FIT 映像)引导流程。这是我用来启动我的板的当前命令序列(输出省略):
setenv bootargs "console=ttyPS0,115200 root=/dev/ram rw ramdisk_size=0x1600000 earlyprintk init=/sbin/init"
tftpboot 0x2000000 devicetree.dtb
tftpboot 0x2080000 uImage
tftpboot 0x4000000 initramfs.img
bootm 0x2080000 0x4000000 0x2000000
Run Code Online (Sandbox Code Playgroud)
我正在开发一个现有项目,据我所知,TFTP 加载地址(0x2080000等)是任意的。我认为它们并不重要,除了它们映射到 RAM 并且不与加载地址重叠这一事实之外。如果我在这里错了,请纠正我。
执行该bootm命令会生成以下输出:
Zynq> bootm 0x2080000 0x4000000 0x2000000
## Booting kernel from Legacy Image at 02080000 ...
Image Name: Linux-4.0.0-00011-gcfd1f62
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3297728 Bytes = 3.1 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying …Run Code Online (Sandbox Code Playgroud)