【问题标题】:Equivalent of .NET's MemoryMarshal in C++ (Arduino)?C++(Arduino)中.NET的MemoryMarshal的等价物?
【发布时间】:2021-04-21 06:57:55
【问题描述】:

我是来自 C# 的 Arduino 和 C++ 开发的新手,因此很可能缺少如此基本的理解。请相应地回答。

上下文

我正在编写一个 Arduino 草图,借此形成一个 Http GET 请求,以便从 Web API 接收数据。在收到响应时,我可以使用client.read(data,client.available()) 将流读入byte data[]。在我的应用程序中,我知道每个 byte 代表一个 ASCII 编码的 char。为了处理响应,我希望将这个byte[] 转换为char[],但这让我开始思考......

问题

如何在 C++ 中将byte[] 转换为另一种已知类型而不复制内存?在 C# 中,我将使用MemoryMarshal 来实现这一点。有些东西告诉我,我应该能够简单地从指针初始化一个对象?

非常感谢

【问题讨论】:

    标签: c++ memory-management casting arduino marshalling


    【解决方案1】:

    byte 不是原生 C++ 类型,Arduino 环境使用typedef 创建它,它实际上是 uint_8(无符号 8 位整数)类型。这也是 char 的底层类型,因此您实际上不必做任何事情。字节数组和字符数组已经是相同的数据类型,只是标记不同。

    您可以使用(char) 强制转换来提高代码清晰度,这不会复制任何数据。

    更新:

    您可以在 C 或 C++ 中使用强制转换来告诉编译器将某些原始数据解释为不同的数据类型。在下面的示例中,包含排列为 XYXYXY 的二维向量的 6 个浮点数组被转换为二维向量结构数组。这是在没有任何数据被复制的情况下完成的。然而,这种技术存在许多缺陷。您需要绝对确定编译器如何布置结构的底层存储。这不是由标准定义的,因此在编译器之间可能会有所不同,许多编译器会为字对齐添加填充,这将根据所使用的体系结构而有所不同。所以请谨慎使用此方法。

    struct My2DVector {
        float x, y;
    }
    
    float flatVectorData[] = { 0.0, 1.0, 2.0, 2.5, -5.0, 3.0};
    
    // Cast the pointer to float to a pointer to My2DVector
    My2DVector* structVectorData = (My2DVector*)flatVectorData;
    
    printf("Vector 2 (%f %f)\n", structVectorData[1].x, structVectorData[1].y);
    

    【讨论】:

    • 很有趣,谢谢,这对我的例子很有帮助。但是,针对“问题”,是否有通用的方法?例如,想象一下我有一个uint_8[6],它相当于一个myStruct[2],每个myStruct 有两个uint_8 类型的字段。这种类型的演员是如何接近的?再次,没有副本。谢谢
    • 我添加了一个希望有意义的示例
    • 完美,谢谢。这就像我期望的那样简单,但由于某种原因或其他原因无法找到明确的答案。我也理解这些操作在没有显式内存管理的情况下的风险,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    相关资源
    最近更新 更多