C(実際にはObj-Cですが、オブジェクト指向はここでは式から外れています)クライアントからPythonサーバーにTCP経由でメッセージを送信しようとしています。ここで、unsigned short
最初にメッセージ サイズを送信し、次に C 構造体であるメッセージを送信しています。パッケージの最後に動的文字列を追加したかったので、構造体のサイズを使用してパッケージを 2 つに分割することにしましたが、問題が発生しました。
問題は、私が何か間違っているか、Python の構造体ライブラリ サイズ + パディング計算にバグがあるかのどちらかです。
Python 構造体は、パディングを正しく解決しているようです。たとえば、次の構造体の場合:
struct.Struct("H I").size == 8
sizeof
この構造体の戻り値と一致します。
#include <stdio.h>
typedef struct {
unsigned short a;
unsigned int b;
} test;
int main() {
printf("%ld\n", sizeof(test));
return 0;
}
$ gcc test.c
$ ./a.out
8
しかし、一部の構造体定義では常に同じ結果が得られるわけではありません。たとえば、この場合:
struct.Struct("H 5s").size == 7
typedef struct {
unsigned short a;
char b[5];
} test;
sizeof(test) == 8
配列で構造体を使用するときに適切なメモリアクセスを確保するために、コンパイラが構造体を埋める可能性があることをどこかで読んだことがあります。これが当てはまるかどうかはわかりませんが(そうであるように思われます)、そうである場合、この構造体が8バイトにパディングされない理由を理解できません(4バイトのパッキングを想定):
struct.Struct("H 4s").size == 6
typedef struct {
unsigned short a;
char b[4];
} test;
sizeof(test) == 6
明確にするために、私の質問は、最終的なパディングを適用していないため、Python で特定の構造体の正確なサイズを取得するにはどうすればよいかということです。
私が試したこと:
最終的なパディング サイズを手動で追加します。
real_struct_size = self._struct.size + self._struct.size % 4
もちろん、これは機能しませんでした。これは、単一のメンバー構造体ではパディングが追加されないためです。最後のケースでわかるように、小さな構造体 (unsigned short + char[4]) でも機能しません。(ここで問題を単純化しすぎているのかもしれません。小さな構造体に関するものではなく、特定できない別の要因に関連している可能性があります。)
次に、Python の struct ライブラリを開いて、予想されるパラメーターの数を確認する方法を確認して、1 であるかどうかを確認し、最終的なパディングを回避できるようにしましたが、のs_len
プロパティにアクセスする方法はありませんPyStructObject
(Python-2.7.5 を参照)。 /Modules/_struct.c:48) は、パックされたパラメーターの数量が格納される場所です。
したがって、回避策として、データ パケットの先頭にオフセット値を配置して、追加/動的文字列の開始位置を把握します。
しかし、ここにバグがあると思います(私のものまたはPythonの構造体ライブラリからのもの)。いずれにせよ、それが私である場合、私が間違っていることを本当に知る必要があります。または、Python のライブラリである場合は、問題を報告したいと思います。誰かがこの問題を解決するのを手伝ってくれたら、とても感謝しています。
それでは、よろしくお願いします!長い投稿で申し訳ありません:)