C++ 在c+中将uint8_t*转换为uint32_t*+;

C++ 在c+中将uint8_t*转换为uint32_t*+;,c++,pointers,casting,fatfs,C++,Pointers,Casting,Fatfs,我正在尝试实现FATFS库的接口函数。该实现需要一个uint8_t*来处理必须由另一个库写入内部SD卡的数据。应使用函数BSP_SD_writeblock(uint32_t*、uint64_t、uint32_t、uint32_t)将数据写入库中。(见下文) 正如您所见,我试图将8位内存地址转换为32位内存地址,但我认为这不是正确的方法 不幸的是,我无法更改函数参数,因此disk_write函数必须接受uint8_t*,而BSP_SD_writeblock只接受uint32_t* 什么是最好的——

我正在尝试实现FATFS库的接口函数。该实现需要一个uint8_t*来处理必须由另一个库写入内部SD卡的数据。应使用函数BSP_SD_writeblock(uint32_t*、uint64_t、uint32_t、uint32_t)将数据写入库中。(见下文)

正如您所见,我试图将8位内存地址转换为32位内存地址,但我认为这不是正确的方法

不幸的是,我无法更改函数参数,因此disk_write函数必须接受uint8_t*,而BSP_SD_writeblock只接受uint32_t*


什么是最好的——也是最快的方式——这样做

诀窍就是首先使用一个大小合适的
uint32\t
数组(它可以动态分配,请参见下面我的第一个想法,但不一定)。任何对象都可以在字节级别访问,因此您可以将
uint32\u t*
强制转换为
uint8\u t*
并将其作为字符缓冲区正常处理:您在字节级别访问原始
uint32\u t
数组,这是严格的别名规则所允许的

当你需要一个
uint32\u t*
的时候,你只需要回溯一下。由于您仅在字节级别访问原始数组,因此数组的生存期尚未结束,
uint32\u t*
指向有效数组


旧的,不太好的解决方案

这里的技巧是通过
malloc
分配缓冲区。C标准在引用C标准库的部分中说,从C++程序(*)可以清楚地访问:7.20.3内存管理功能< /P> 。。。如果分配失败,指针将返回 SUCCESS适当对齐,以便可以将其指定给指向任何类型对象的指针 然后用于访问分配空间中的此类对象或此类对象数组

这意味着提供的
buffer
malloc
调用的返回值,标准保证可以安全地将其转换为任何其他指针类型

如果不这样做,您将面临对齐问题的风险,因为
uint32\u t
的对齐度高于
uint8\u t
,并且使用错误的对齐指针显然是未定义的行为

有人可能会说,我们在这里违反了严格的别名规则。但是任何通用的实现都可以使用它(它会破坏太多的现有代码而拒绝),唯一严格一致的方法是使用缓冲区的完整memcopy。。。以完全相同的字节序列和兼容的对齐方式结束


<>(*)我知道C和C++是不同的语言,但是C++标准参考手册在1.2个规范性引用中引用了[参考文献] < /P> 1下列参考文件对于本文件的应用是必不可少的
-ISO/IEC 9899:1999,编程语言-C

2 ISO/IEC 9899:1999第7条和ISO/IEC 9899:1999/Cor.1:2001第7条中所述的库 ISO/IEC 9899:1999/Cor.2:2003第7条以下称为C标准库

1)第18至30条和第三条中所列的条件,C标准库是C++标准的一个子集。 图书馆


诀窍就是首先使用一个大小合适的
uint32\t
数组(它可以动态分配,请参见下面我的第一个想法,但不一定)。任何对象都可以在字节级别访问,因此您可以将
uint32\u t*
强制转换为
uint8\u t*
并将其作为字符缓冲区正常处理:您在字节级别访问原始
uint32\u t
数组,这是严格的别名规则所允许的

当你需要一个
uint32\u t*
的时候,你只需要回溯一下。由于您仅在字节级别访问原始数组,因此数组的生存期尚未结束,
uint32\u t*
指向有效数组


旧的,不太好的解决方案

这里的技巧是通过
malloc
分配缓冲区。C标准在引用C标准库的部分中说,从C++程序(*)可以清楚地访问:7.20.3内存管理功能< /P> 。。。如果分配失败,指针将返回 SUCCESS适当对齐,以便可以将其指定给指向任何类型对象的指针 然后用于访问分配空间中的此类对象或此类对象数组

这意味着提供的
buffer
malloc
调用的返回值,标准保证可以安全地将其转换为任何其他指针类型

如果不这样做,您将面临对齐问题的风险,因为
uint32\u t
的对齐度高于
uint8\u t
,并且使用错误的对齐指针显然是未定义的行为

有人可能会说,我们在这里违反了严格的别名规则。但是任何通用的实现都可以使用它(它会破坏太多的现有代码而拒绝),唯一严格一致的方法是使用缓冲区的完整memcopy。。。以完全相同的字节序列和兼容的对齐方式结束


<>(*)我知道C和C++是不同的语言,但是C++标准参考手册在1.2个规范性引用中引用了[参考文献] < /P> 1下列参考文件对于本文件的应用是必不可少的
-ISO/IEC 9899:1999,编程语言-C

2 ISO/IEC 9899:1999第7条和ISO/IEC 9899:1999/Cor.1:2001第7条中所述的库 ISO/IEC 9899:1999/Cor.2:2003第7条以下称为C标准库

1)第18至30条和第三条中所列的条件,C标准库是C++标准的一个子集。 图书馆


有可能是多重的
/*
 * Write data from a specific sector
 */
int SDMMC::disk_write(const uint8_t *buffer, uint32_t sector, uint32_t count)
{
    int res = BSP_SD_WriteBlocks((uint32_t*)buffer, (uint64_t)sector, 512, count);

    if (res == MSD_OK) {
        return RES_OK;
    } else {
        return RES_ERROR;
    }
}