Created
February 19, 2022 22:51
-
-
Save helo9/04125ae67b493e505d5dce4b254a2ccc to your computer and use it in GitHub Desktop.
Problem with ctypes bitfield
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "a1afba99-d7b1-484c-97c4-8f145920ba96", | |
"metadata": {}, | |
"source": [ | |
"# ctypes bitfield problem\n", | |
"\n", | |
"I have some binary data, produced with C/C++. When using the code given below,\n", | |
"something seems to be a bit off. Probably I missed some flag or so.\n", | |
"\n", | |
"An example of the data is:\n", | |
"\n", | |
"```\n", | |
"bytes([67, 165, 195, 254, 255, 18, 0, 191, 0, 64])\n", | |
"```" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "a836ad4f-9ce1-4eee-9b0c-266aaa404883", | |
"metadata": {}, | |
"source": [ | |
"# packing using C/C++" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"id": "2189afd9-abab-4408-8149-623693ee0d08", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting test.cpp\n" | |
] | |
} | |
], | |
"source": [ | |
"%%writefile test.cpp\n", | |
"\n", | |
"#include <iostream>\n", | |
"#include <cstdint>\n", | |
"\n", | |
"#define MSG_LEN 10\n", | |
"\n", | |
"using namespace std;\n", | |
"union measurement_msg {\n", | |
" struct __attribute__((__packed__)) {\n", | |
" uint16_t ts : 16;\n", | |
" int32_t gyro_x : 20;\n", | |
" int32_t gyro_y : 20;\n", | |
" int32_t gyro_z : 20;\n", | |
" } values;\n", | |
" std::uint8_t raw[MSG_LEN];\n", | |
"};\n", | |
"\n", | |
"int main()\n", | |
"{\n", | |
" union measurement_msg test;\n", | |
" \n", | |
" test.values.ts = 42307;\n", | |
" test.values.gyro_x = -317;\n", | |
" test.values.gyro_y = 303;\n", | |
" test.values.gyro_z = 191;\n", | |
" \n", | |
" for (auto &val : test.raw) {\n", | |
" cout << (int)val << \", \";\n", | |
" }\n", | |
" cout << endl;\n", | |
"\n", | |
" return 0;\n", | |
"}" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "de7120ef-5fa4-44d3-aa8f-77a7452f091e", | |
"metadata": {}, | |
"source": [ | |
"WARNING: next file compiles and runs code on your computer" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 55, | |
"id": "31124e46-b7bd-42dd-8f6f-b1cf5a903bca", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"67, 165, 195, 254, 255, 18, 0, 191, 0, 0, \n" | |
] | |
} | |
], | |
"source": [ | |
"!g++ test.cpp && ./a.out" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "e4532b3e-bf0f-43b0-a388-8bafd769e981", | |
"metadata": {}, | |
"source": [ | |
"## ctypes unpacking\n", | |
"\n", | |
"using `67 165 195 254 255 18 0 191 0 0`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 31, | |
"id": "e6acb961-3c2f-4a60-89a7-0dd434285507", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from ctypes import *\n", | |
"\n", | |
"MSG_LEN = 10\n", | |
"\n", | |
"class Values(LittleEndianStructure):\n", | |
" _pack_ = 1\n", | |
" _fields_ = [\n", | |
" (\"ts\", c_uint16, 16), \n", | |
" (\"gyro_x\", c_int32, 20),\n", | |
" (\"gyro_y\", c_int32, 20),\n", | |
" (\"gyro_z\", c_int32, 20)\n", | |
" ]\n", | |
"\n", | |
"class Data(Union):\n", | |
" _fields_ = [(\"values\", Values), (\"raw\", c_ubyte * MSG_LEN)]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 56, | |
"id": "24a6ae71-56f3-481d-8c72-9275c8ac0589", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(42307, -317, 48896, 0)" | |
] | |
}, | |
"execution_count": 56, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"example = Data()\n", | |
"\n", | |
"#example.raw = bytes([67, 165, 195, 254, 255, 18, 0, 191, 0, 64])\n", | |
"example.raw = (c_ubyte*10)(67, 165, 195, 254, 255, 18, 0, 191, 0, 0)\n", | |
"example.values.ts, example.values.gyro_x, example.values.gyro_y, example.values.gyro_z" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "c00856a0-1758-4a59-a2d2-ddb3259c5e21", | |
"metadata": {}, | |
"source": [ | |
"result is off starting from `gyro_y` :(" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "af26670a-5aa6-4624-9485-86a2eb035133", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.10.2" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment