C言語の構造体をpythonで実装する方法

このQ&Aのポイント
  • C言語の構造体をpythonで実装する方法について教えてください。
  • 現在ラズベリーパイでpythonでTCPクライアントを作成していますが、サーバーに特定のパケットを送信する必要があります。
  • それには、C言語の構造体と同じバイト数のデータをpythonで作成する必要があります。どのように実装すればよいでしょうか?
回答を見る
  • ベストアンサー

C言語の構造体をpythonでやりたい

現在ラズベリーパイでpythonでTCPクライアントを作っています。 現在サーバーに次のようなパケットを送信したいと思っているのですが、このC言語の構造体を同じバイト数で出力するようにpython言語にすることは可能でしょうか? どうぞ、ご教示いただきますよう、宜しくお願い致します。 typedef struct _PAYLOAD_ALIVE_ { BYTE MacAddr[6]; WORD Port; BYTE Relay; BYTE Set; BYTE AliveTime; BYTE SensorLen; BYTE Mail[40]; WORD Model[20]; BYTE testArea[4]; BYTE SWVer[4]; BYTE testSensor[16]; }PL_ALIVE;

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.1

struct.packとstruct.unpackを使います。 http://docs.python.jp/2/library/struct.html サンプルは、「Python struct」で検索すると見つかります。

techhouse
質問者

お礼

回答頂きありがとうございます。 pythonでも構造体のような使い方ができるようですね。 助かります。

関連するQ&A

  • 構造体メンバがポインタであるときの代入

    typedef struct WRITE_BUF_TYPE{  byte adr_h; // ワードアドレス上位  byte adr_l; // ワードアドレス下位  byte *buf_adr; // 送信/受信先 アドレス  byte cnt; // 文字数 }; struct W_BUF_TYPE b[10]; 構造体、データ定義を上のようにしています。 b[10]の空きを探して書き込むサブルーチンを作ったのですが、*buf_adrの設定方法がわかりません。 ご存知の方、教えてください。 サブルーチン sub_func(int8 *adr){  byte i;  for(i=0;i<10;i++){    if(b[i].adr_h==0){  // b[10]の空き検索    b[i].buf_adr=*adr; // アドレスを設定する。ここでエラーとなります。  } } サブルーチンでバッファのアドレスを受けて、b[10]の空きエリアに設定するプログラムです。

  • C言語での構造体の定義と初期化

    こんにちは。 C言語での構造体の定義と初期化について質問させてください。 現在、ファイル操作に関する自作ライブラリをいじっており、その中でファイルのパス名を分解する関数を作成しました。 関数自体は出来上がっており、リンクさせて動作テストをしているのですが、コンパイラが各オブジェクトをコンパイルしているときに警告が発生し、どうやっても解消しません。 gccはエラーを吐いて、コンパイルはしてもリンクしてくれません。 Bccでは警告だけで無理矢理リンクしているようですが、何故か実行ファイルが494 KB、通常の4倍以上のサイズに肥大してしまいます(コマンドラインツールなので通常は大きくても100KB程度)。 警告の原因と対処について、どなたかアドバイスをお願いします。 以下状況を簡単に説明します。 開発環境は、 PC:WinXP sp3 開発環境1:「Borland C++ compiler 5.5.1」 「MAKE Version 5.2」 開発環境2:「gcc version 3.4.5 (mingw special)」 「GNU Make version 3.79.1」 です。各環境につきMAKEFILEがあり、どちらでもコンパイルできるようにしてあります。 ヘッダファイルは長いので、全体は後で貼り付けますが、問題となっているのは多分次の部分です。 構造体のメンバとして6種類の文字配列をもち、この中にパス名やファイル名などを格納します。 struct st_split_path{ char drive [MAX_FULLPATH];//ドライブ名 char dirpath[MAX_FULLPATH];//ディレクトリパス char dir [MAX_FULLPATH];//直属のディレクトリ名 char fname [MAX_FULLPATH];//ファイル名 char fname2 [MAX_FULLPATH];//ファイル名(拡張子抜き) char ext [MAX_FULLPATH];//拡張子(ドットつき) int buffsize; } st_split_path = { {'\0'}, {'\0'}, {'\0'}, {'\0'}, {'\0'}, {'\0'}, MAX_FULLPATH, }; typedef struct st_split_path SPLIT_PATH; きちんと初期化された構造体を宣言した後、typedefで新しい型として定義しています。 初期化しないなら宣言は typedef struct SPLIT_PATH{ char drive [MAX_FULLPATH];//ドライブ名 char dirpath[MAX_FULLPATH];//ディレクトリパス char dir [MAX_FULLPATH];//直属のディレクトリ名 char fname [MAX_FULLPATH];//ファイル名 char fname2 [MAX_FULLPATH];//ファイル名(拡張子抜き) char ext [MAX_FULLPATH];//拡張子(ドットつき) int buffsize; } SPLIT_PATH; とするところですが、文字配列が6つもあるので、初期化を予めしておきたいと考えた次第です。 これで次のようなエラー(警告)が出ます。 Bcc Warning: パブリックシンボル _st_split_path がモジュール E:\WORK\FILE_CMP.OBJ と E:\WORK\LIB-FILE.OBJ の両方に定義されている gcc Lib-file.obj:Lib-file.c:(.data+0x0): multiple definition of `st_split_path' File_cmp.obj:File_cmp.c:(.data+0x0): first defined here 多分、ヘッダを取り込んだ先でそれぞれ宣言されてリンク時に名前がかち合っているのだと推察できますが、理由がよく分かりません。 これはあくまで構造体定義で、実体は呼び出し側で SPLIT_PATH sppath; として宣言していると考えています。 また、ヘッダファイル自体は多重インクルードガードをかけていますので、別のヘッダがこいつを再度取り込んでいるとは考えられません。 また、何らかの原因で実体を持っているのなら、extern 宣言で解決できると思い、 } st_split_path = { を } extern st_split_path = { ともしてみましたが状況は変わりませんでした。 私がexternを理解できていないだけかもしれませんが、他に解決策は思いつきません。 もしかして定義と初期化は同時にはできないのでしょうか。 google検索で「C言語 構造体 定義と同時に初期化」と検索しても、一応できるとは書いてあるのですが、サイトによって構造体宣言と定義が区別されてないようなサイトもあり、よく分かりません。 どなたかご教授ください。 長いのですが、次に問題があるであろうヘッダファイルの抜粋を載せておきます。 ヘッダ"Lib-file.h"の抜粋です。 問題ない構造体宣言や、雑多な関数宣言以外は、マクロ定義を含めそのままです。 #ifndef Lib_file_h //自分自身の定義 #define Lib_file_h #include "Lib-macro.h" /****************************************************************/ /**************** 環境依存につきifdef条件include ****************/ /****************************ここから****************************/ #ifdef __GNUC__ #include <sys/utime.h> #endif #ifdef _MSC_VER #include <sys/utime.h> #endif #ifdef __BORLANDC__ #include <utime.h> #endif #ifdef __INTEL_COMPILER #include <sys/utime.h> #endif /****************************ここまで****************************/ /**************** 環境依存につきifdef条件include ****************/ /****************************************************************/ #include <time.h> #include <sys/stat.h> #include <io.h> #include <fcntl.h> #define MAX_FULLPATH (255*128) struct st_split_path{ char drive [MAX_FULLPATH];//ドライブ名 char dirpath[MAX_FULLPATH];//ディレクトリパス char dir [MAX_FULLPATH];//直属のディレクトリ名 char fname [MAX_FULLPATH];//ファイル名 char fname2 [MAX_FULLPATH];//ファイル名(拡張子抜き) char ext [MAX_FULLPATH];//拡張子(ドットつき) int buffsize; } st_split_path = { {'\0'}, {'\0'}, {'\0'}, {'\0'}, {'\0'}, {'\0'}, MAX_FULLPATH, }; typedef struct st_split_path SPLIT_PATH; #ifdef __cplusplus extern "C" { #endif time_t file_mtime_get(char *fname); int split_path(char *fullpath,SPLIT_PATH *sppath); int fpath_regularization(char *fullpath); #ifdef __cplusplus }; #endif #endif

  • ポインタ版リスト構造によるスタックの実装

    C言語を用いてアルゴリズムの勉強をしています。 現在、ポインタ版リスト構造によるスタックを実装し、入力された文字列の中で括弧の整合性を判定するプログラムを作成しているのですが、難航しています。 プログラムの内容は、以下の通りです。 入力:a{z[e(b){j}(p)]w}(j) 結果:整合 入力:a{z[e(b){j}(p)}w](j) 結果:不整合 ですが、所持している参考書の例題プログラムには、スタックに入れる要素が整数値のものしかなく、文字をスタックに入れるところからわかりません。 また、先輩に尋ねたところ、以下のような構造体を使うと良いとアドバイスされました。 typedef struct { int max; int num; List stk; } Stack; typedef struct { Node *head; Node *crnt; } List; typedef struct node { char data; struct node *next; } Node; 先輩には申し訳ないのですが、余計にわからなくなってしまいました。 この構造体を用いてプログラムをかける方、ご指導のほどよろしくお願いします。

  • sizeofの処理

    お世話になります sizeof()の処理について教えてください typedef struct {   BYTE m_bDat;   WORD m_wWord; }tTEMP; sizeof( tTEMP ); この場合、アライメントは最小としたとして、サイズは3と帰ってくるとします。 アライメントをコンパイルオプション等を使用して、2として再度sizeofを行います この際、値は4となると思います 知りたいのは、sizeofの処理方法です よろしくお願い致します

  • C言語で作成するチャットについて

    LinuxでC言語のチャットプログラムを作成しています。プログラムを作ってみましたがうまく動きません。悪い個所が分からないのでお力を貸して頂きたいです課題の提出が迫っているので、よろしくお願いいたします。 <server> #include省略 #define PORT 5320 char *show_ip(char *ip_address); int main(void){ int soc, acc, size, child[3],width,i,count,pos,ret; char buffer[80]; struct sockaddr_in client, server; struct sockaddr_storage from; struct hostent *server_host; socklen_t len; fd_set mask; char host_name[257]; int temp; memset(host_name, 0, sizeof(host_name)); gethostname(host_name, 256); server_host = gethostbyname(host_name); printf("\n-------- informations of server ----------\n"); printf("Host name:%s\n", host_name); printf("IP = %s\n", show_ip(server_host->h_addr)); printf("\n\n"); soc = socket(AF_INET, SOCK_STREAM, 0); memset((char *)&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = htons(PORT); bind(soc, (struct sockaddr *)&server, sizeof(server)); size = sizeof(client); listen(soc, 5); for (i = 0; i < 3; i++){ child[i] = -1; } for (;;) { FD_ZERO(&mask); FD_SET(soc, &mask); for (i = 0; i < 3; i++) { if (child[i] != -1){ FD_SET(child[i], &mask); if(child[i]+1 > width){ width = child[i]+1; } } } switch(select(soc+1, (fd_set *) &mask, NULL, NULL, NULL)) { case -1: perror("select"); break; case 0: break; default: if (FD_ISSET(soc, &mask)){ len = (socklen_t) sizeof(from); if((acc = accept(child[i], (struct sockaddr *)&from, &len)) == -1){ if(errno != EINTR){ perror("accept"); } }else{ if(child[0]&&child[1]&&child[2]!=-1){ fprintf(stderr,"child is full : cannot accept\n"); close(acc); }else{ if(child[0] == -1){ child[0] = acc; }else if(child[1] == -1){ child[1] = acc; }else{ child[2] = acc; } } } } for(i=0;i<3;i++){ if(child[i]!=-1){ if(FD_ISSET(child[i],&mask)){ memset(buffer, '\0', sizeof(buffer)); recv(child[i], buffer, 80, 0); printf("%s> ", show_ip((char *)&client.sin_addr)); printf("%s", buffer); if(strncmp(buffer, "exit", 4) == 0) break; for(i=0;i<3;i++) { send(child[i],show_ip((char *)&client.sin_addr),80,0); send(child[i],buffer,80,0); close(child[i]); } (void) close(child[i]); child[i] = -1; } } break; } } } } char *show_ip(char *ip_address){ static char ip[7]; char ipnum[4]; bcopy(ip_address, ipnum, 4); sprintf(ip, "%u.%u.%u.%u",(unsigned char)ipnum[0], (unsigned char)ipnum[1], (unsigned char)ipnum[2],(unsigned char)ipnum[3]); return ip; } <client> #include省略 #define STDIN_FD 0 #define PORT 5320 int select_func(int sockfd); void err_func(char *msg){ perror(msg); exit(EXIT_FAILURE); } int main(int argc, char **argv){ int sockfd, len; char buf[BUFSIZ]; struct sockaddr_in serv; unsigned short port; if(argc != 3){ printf("usage: progname serv_ip serv_port\n"); exit(EXIT_FAILURE); } if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err_func("socket"); serv.sin_family = PF_INET; port = (unsigned short)atoi(argv[2]); serv.sin_port = htons(port); inet_aton(argv[1], &(serv.sin_addr)); if(connect(sockfd, (struct sockaddr *)&serv, sizeof(struct sockaddr_in)) < 0) err_func("connect"); do{ if(select_func(sockfd) == 0){ len = recv(sockfd, buf, BUFSIZ, 0); buf[len] = '\0'; printf("-> %s\n", buf); }else{ len = read(STDIN_FD, buf, BUFSIZ); len = send(sockfd, buf, len, 0); } }while(strncmp(buf, "EXIT\r\n", 6) != 0 && strncmp(buf, "EXIT\n", 5) != 0); close(sockfd); return 0; } int select_func(int sockfd){ fd_set rfds; FD_ZERO(&rfds); FD_SET(sockfd, &rfds); FD_SET(STDIN_FD, &rfds); if(select(sockfd+1, &rfds, NULL, NULL, NULL) < 0) err_func("select"); if(FD_ISSET(STDIN_FD, &rfds)) return STDIN_FD; return sockfd; }

  • 構造体とポインタ配列

    現在C言語の勉強をしております。 環境はwindowsXP、コンパイラはVC6.0です。 構造体と、ポインタの配列についてなのですが、 以下のような構造体が宣言されている時に、リスト構造にデータがいくつか入っているとします。 // 構造体 typedef struct address { unsigned char names[NAME_SIZE+1]; /* 名前 */ char tels[TEL_SIZE + 1]; /* 電話番号 */ struct address *prev; /* 前へのポインタ */ struct address *next; /* 次へのポインタ */ }Address, *a_pt; そのリスト構造を先頭要素か順番にポインタ配列に格納するには以下の方法ではおかしいでしょうか? /* ポインタ配列を用意する */ Address *array[MAX_COUNT]; /* top_ptは先頭のポインタです */ pt = top_pt; /* データがなくなるまで配列へ格納する */ while(pt != NULL){ array[count++] = pt; pt = pt->next; } /* 配列の最後はNULLとする */ array[count] = NULL; また、配列の中身を確認する方法としては、 printf("配列の中身:%s\n", array[0]->names); では、アドレスが表示されてしまうのかな・・と思ったら、accessViolationで落ちてしまいました・・・。 中身はどうしたらデバッグ出来ますでしょうか? そもそも、以下の2つは何か違いはありますか? Address *ptA[100]; a_pt ptB[100]; 皆さん、どうかよろしくお願いいたします。 理解不能な場合はご指摘ください。

  • 構造体の中身の2次元配列をファイルに書き込むことができるのでしょうか?

    構造体の中身の2次元配列をファイルに書き込むことができるのでしょうか? 現在、入力したデータをファイルに保存するプログラムを作成しております。 fp = fopen(file_name, "wb"); fwrite( &save_data, sizeof(save_data_t), 1, fp ); このように構造体ごとファイルに書き込んでいるのですが、 fread()で読みだした時に、2次元配列が読み込まれていません。 (おそらく書き込み自体ができていなかったのだとおもいます。) どのようにすれば、構造体の中に含まれている 2次元配列を書き込むことができるのでしょうか? c言語初心者ですので、是非ともよろしくお願いします。 typedef struct Save_Data{ int s_num; char s_page[][260]; }save_data_t; save_data_t save_data;

  • 構造体配列ポインタを引数で使うには

    いつもお世話になってます。 C言語を使って、構造体配列を引数として使って、サブ関数で取得した値(配列)をメイン関数に渡したいと思っているのですが、受け渡しが上手くできません。 現在以下の様に組んでいます。 /* 構造体宣言 */ typedef struct EXP1 { char sTime[17]; /* 開始日時 */ struct { int num; /* データ数 */ float data[96]; /* データ */ } getdata[5]; } EXP1 ; /* メイン関数 */ int func1( EXP1 ex1; for( loop = 0 ; loop < 5 ; loop++){ ans = funcGet( array1, &ex1.getdata[loop].data ); } if( ans = 0 ){ for( loop = 0 ; ; loop++){ printf("%f",ex1.data[count].pvdata[loop] ); } } } /* サブ関数 */ static int funcGet(int array, float *fvalue) { ans = calcvalu( array, fvalue ); //←float型で値が取得される。 for( i = 0 ; i < 10 ; i++ ) { printf("%f", *(fvalue + i); } return 0; } サブ関数で"fvalue"を確認したところ、正常に値が取得できているのですが、メイン関数では取得できていません。 どうかアドバイスをよろしくお願いします。

  • 各言語の用途と代表的なソフトウエアを教えてください。

    現在、いろいろなプログラム言語がどの用途に強いかを調べています。 その一環として、あるプログラム言語で作成した代表的なソフトウエアが判れば理解の助けになると思い質問した次第です。 調査対象の言語は、C、C++、JAVA、PL/I、VBです。 できれば以下の形式でご回答いただければと思います。 例:言語=VB    用途=WINDOWS上で動くソフト全般   代表的ソフト=WORD,EXECL よろしくお願いします。

  • win32api構造体引数の型指定について

    win32api構造体引数の型指定について selfesteemと申します。 midiを利用するアプリを作成するために 初めてwin32apiに挑戦しています。(WindowsVista,VB2008.net) 構造体引数の渡し方がまずいのかうまくいきません。 詳しい方教えていただけませんでしょうか? よろしくお願いします。 ・利用したいAPI midiOutGetDevCaps ・発生するエラー ArgumentException 型 'UInt32' のフィールド '_vDriverVersion' を持つ構造体のファイル入出力 (I/O) は無効です。 ・MMSystem.hでの定義(抜粋) WINMMAPI MMRESULT WINAPI midiOutGetDevCapsA( __in UINT_PTR uDeviceID, __out_bcount(cbmoc) LPMIDIOUTCAPSA pmoc, __in UINT cbmoc); typedef UINT MMVERSION; /* major (high byte), minor (low byte) */ typedef struct tagMIDIOUTCAPSA { WORD wMid; /* manufacturer ID */ WORD wPid; /* product ID */ MMVERSION vDriverVersion; /* version of the driver */ CHAR szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */ WORD wTechnology; /* type of device */ WORD wVoices; /* # of voices (internal synth only) */ WORD wNotes; /* max # of notes (internal synth only) */ WORD wChannelMask; /* channels used (internal synth only) */ DWORD dwSupport; /* functionality supported by driver */ } MIDIOUTCAPSA, *PMIDIOUTCAPSA, *NPMIDIOUTCAPSA, *LPMIDIOUTCAPSA; ・実際のAPI呼び出しのソースコード(VB) Imports System.Runtime.InteropServices Private Declare Function midiOutGetDevCaps Lib "winmm.dll" Alias "midiOutGetDevCapsA" (ByVal uDeviceID As UInt32, _ ByRef lpCaps As MIDIOUTCAPS, _ ByVal uSize As UInt32) As Long <StructLayout(LayoutKind.Sequential)> _ Structure MIDIOUTCAPS Public wMid As Short Public wPid As Short Public _vDriverVersion As UInt32 <MarshalAs(UnmanagedType.LPTStr)> Dim szPname As String Public wTechnology As Short Public wVoices As Short Public wNotes As Short Public wChannelMask As Short Public dwSupport As Long End Structure Sub main() Dim ret As Long Dim mc As New MIDIOUTCAPS ret = midiOutGetDevCaps(0, mc, Len(mc)) ←ここでエラー End Sub

専門家に質問してみよう