繁体   English   中英

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

[英]How do I extract little-endian unsigned short from long pointer?

我有一个长指针值,它指向一个20字节的标头结构,后跟一个更大的数组。 Dec(57987104)=十六进制(0374D020)。 所有值都存储为little endian。 交换时的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;
}

但是,当我使用Debug.Print getUnsignedShort(57987104)从VBA调用此函数时,应得到30008(应为20)。

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

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

如何从长指针中提取小端无符号的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>导出的大小整数类型。

编辑:

刚刚意识到您的数据实际上是小端:)

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));
}

假设您用pulong指向pulong [6]您指向的是表格的第六个成员

unsigned short psh*; unsigned char puchar* unsigend char ptable[4]; ZeroMemory(ptable,4); puchar[3]=((char *)( &pulong[6]))[0]; puchar[2]=((char *)( &pulong[6]))[1]; puchar[1]=((char *)( &pulong[6]))[2]; puchar[0]=((char *)( &pulong[6]))[3]; psh=(unsigned short *) puchar; //first one psh[0]; //second one psh[1];
这就是我误会我的想法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM