如何从长指针中提取 little-endian unsigned short?

D_Bester

我有一个长指针值,指向一个 20 字节的头结构,后跟一个更大的数组。十二月(57987104)=十六进制(0374D020)。所有的值都以小端存储。交换时的 1400 为 0014,十进制为 20。

在此处输入图片说明

这里的问题是如何获得第一个值,它是一个 2 字节的无符号短整型。我有一个 C++ dll 来为我转换它。我正在运行 Windows 10。

GetCellData_API unsigned short __stdcall getUnsignedShort(unsigned long ptr) 
{
    unsigned long *p = &ptr;
    unsigned short ret = *p;
    return ret;
}

但是当我使用 VBA 调用Debug.Print getUnsignedShort(57987104)它时,我得到 30008,而它应该是 20。

我可能需要进行字节序交换,但我不确定如何从CodeGuru合并此内容:如何在大端和小端值之间进行转换?

inline void endian_swap(unsigned short& x)
{
    x = (x >> 8) |
        (x << 8);
}

如何从长指针中提取 little endian unsigned short?

理查德·霍奇斯

我想我倾向于根据描述操作的通用模板函数来编写您的接口函数:

#include <utility>
#include <cstdint>

// Code for the general case
// you'll be amazed at the compiler's optimiser
template<class Integral>
auto extract_be(const std::uint8_t* buffer)
{
    using accumulator_type = std::make_unsigned_t<Integral>;

    auto acc = accumulator_type(0);
    auto count = sizeof(Integral);

    while(count--)
    {
        acc |= accumulator_type(*buffer++) << (8 * count);
    }

    return Integral(acc);
}



GetCellData_API unsigned short __stdcall getUnsignedShort(std::uintptr_t ptr) 
{
    return extract_be<std::uint16_t>(reinterpret_cast<const std::uint8_t*>(ptr));
}

正如您在 Godbolt 上演示中看到的那样,编译器为您完成了所有繁重的工作。

请注意,由于我们知道数据的大小,因此我使用了从中导出的大小整数类型<cstdint>,以防需要将此代码移植到另一个平台。

编辑:

刚刚意识到您的数据实际上是 LITTLE Endian :)

template<class Integral>
auto extract_le(const std::uint8_t* buffer)
{
    using accumulator_type = std::make_unsigned_t<Integral>;

    auto acc = accumulator_type(0);
    constexpr auto size = sizeof(Integral);

    for(std::size_t count = 0 ; count < size ; ++count)
    {
        acc |= accumulator_type(*buffer++) << (8 * count);
    }

    return Integral(acc);
}


GetCellData_API unsigned short __stdcall getUnsignedShort(std::uintptr_t ptr) 
{
    return extract_le<std::uint16_t>(reinterpret_cast<const std::uint8_t*>(ptr));
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Little Endian与Big Endian架构

如何在 C# 中读取 Little Endian 编码文件?

如何将boost :: multiprecision :: cpp_int从big endian更改为little endian

如何在Java(endian)中渲染GL_SHORT?

将Little Endian转换为Big Endian

检查系统为Little Endian或Big Endian

Little Endian和nasm推送

如何在opengl着色器中使用unsigned short?

如何检查将char * []转换为unsigned short的溢出

如何将 unsigned short 7273 转换为 ascii HI

Big Endian和Little Endian支持字节排序

如何在C ++中将unsigned int转换为两个unsigned short?

首先读取Little Endian – LS字节为整数,如何忽略多余的0

如何从字节缓冲区中读取 little-endian 64 位值?

如何使用Ruby解析以little-endian格式给出的64位整数的时间戳?

在Little Endian CPU体系结构上运行时,Java如何处理Endianess?

如何在Jasper JPEG2000中指定Little Endian

如何从Little-Endian UTF-16编码字节中获取C ++ std :: string

如何在C ++中将Big / Little-Endian字节转换为Integer,反之亦然

如何将Int转换为8字节的little-endian

C ++中unsigned int与unsigned short的区别

(java)在文件little endian中写入

如何在 Python 中从二进制文件读取和写入“Unicode(UTF-16 little endian)”文本?

unsigned short int和unsigned int或unsigned short之间有什么区别?

如何在C中將short轉換為unsigned char *buf?

如何将 unsigned short* 从 Visual-C++ DLL 传递到 VB.NET

将unsigned short *强制转换为unsigned int *

使用unsigned int而不是unsigned short更改行为

将数据发送到Little Endian的串行端口