Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lisp側のdefcstructで,byte, short, int型以外の型を定義する必要があると思うのですが,そのようなことは可能なのでしょうか? #460

Open
k-okada opened this issue May 6, 2021 · 1 comment

Comments

@k-okada
Copy link
Member

k-okada commented May 6, 2021

解決したか解決していないのかわからなかったのですが,
defcstruct では型を定義する必要はなくて,ポインタの長さを書けば良いんだと思います.
難しいのは,コンパイルしたときに構造体の要素の置かれる位置がバイト境界になることで,
コンパイラオプション等々に依存することです.

やりたいこととのCサンプルプログラム(構造体を定義して,構造体受け取って中身を表示する関数?)
があるとLisp側のサンプルプログラムが作れると思います.

;; typedef struct {
;; int type; /* of event */
;; unsigned long serial; /* # of last request processed by server */
;; Bool send_event; /* true if this came from a SendEvent request */
;; Display *display; /* Display the event was read from */
;; Window window; /* "event" window reported relative to */
;; Window root; /* root window that the event occurred on */
;; Window subwindow; /* child window */
;; Time time; /* milliseconds */
;; int x, y; /* pointer x, y coordinates in event window */
;; int x_root, y_root; /* coordinates relative to root */
;; unsigned int state; /* key or button mask */
;; char is_hint; /* detail */
;; Bool same_screen; /* same screen flag */
;; } XMotionEvent;
;;; event processing
(defcstruct XEvent
(type :integer) ;0
(serial :long) ;1
(send-event :integer) ;2
(display :long) ;3
(window :long) ;4
(root :long) ;5
(subwindow :long) ;6
#-:alpha
(time :long) ;7
#+:alpha
(time :integer) ;7
(x :integer) ;8
(y :integer) ;9
(x-root :integer) ;10
(y-root :integer) ;11
(state :integer) ;12
(detail :integer) ;13
(same-screen :integer) ;14
(focus :integer) ;15
(alt-state :integer) ;16
#-(or :alpha :irix6 :word-size=64)
(pad :char 28) ;xevent is required to hold 24 longs
#+:irix6
(pad :char 84)
#+:alpha
(pad :char 88)
#+(or :word-size=64)
(pad :char 92) ;xevent is required to hold xx longs at x86-64
)

@chibi314, @inabajsk

@inabajsk
Copy link
Contributor

inabajsk commented May 7, 2021

基本型の名前で:integerが4バイトか8バイトかわかりにくいので,
sizeof-typesという大域変数にサイズが書いてあるので

(setq sizeof-types
      `((:uint32_t 4)
	(:uint16_t 2)
	(:pointer ,lisp::sizeof-*) (:long ,lisp::sizeof-long)
	(:int ,lisp::sizeof-int) (:integer ,lisp::sizeof-int)
	(:short ,lisp::sizeof-short) (:char ,lisp::sizeof-char)
	(:character ,lisp::sizeof-char) (:float ,lisp::sizeof-float)
	(:double ,lisp::sizeof-double) (:word 2) (:byte 1)))

のようにすると,:uint32_tとか:uint16_tのような名前で

(defcstruct jointbase-sensor-cstruct	;; SensorbaseStruct sensorbase_t in main.h
  (port :byte)
  (id :byte)
  (mode :byte)
  (sw :byte)
  (adc :short 4)
  (ps :short 4)
  (gyro :short 3)
  (acc :short 3)
  (rxerror_count :byte)
  (timeout_count :byte)
  (debug_rxbuff :byte 2)
  (count_frame :uint32_t)
  (prev_frame :uint32_t)
  (adc_calib :short 25)
  ;;(adc_calib c-array5 5)
  (force :float 4)
  )

のような定義に使えます.

defcstructの構造体の名前を新しい型名として使うこともできて,

(defcstruct object-detection-result-cstruct
  (x :short)
  (y :short)
  (w :short)
  (h :short)
  (confidence :byte)
  (class_id :byte)
  )

と定義した型を

(defcstruct m5stickv-cstruct
  (is_exist :byte)
  (i2c_id :byte)
  (i2c_state :byte)
  (led_state :byte)
  (record_image :byte)
  (result_num :byte)
  (result0 object-detection-result-cstruct)
  (result1 object-detection-result-cstruct)
  (result2 object-detection-result-cstruct)
  (result3 object-detection-result-cstruct)
  (result4 object-detection-result-cstruct)
  (result5 object-detection-result-cstruct)
  (result6 object-detection-result-cstruct)
  (result7 object-detection-result-cstruct)
  )

のような新しいdefcstructの構造体定義に利用することも
できます.C側の構造体定義は,

#define M5STICKV_MAX_DETECTION_RESULT_NUM 8
typedef struct M5StickVStruct {
	uint8_t is_exist;
	uint8_t i2c_id;
	uint8_t i2c_state;
	uint8_t led_state;
	uint8_t record_image;
	uint8_t result_num;
	object_detection_result_t detection_result[M5STICKV_MAX_DETECTION_RESULT_NUM];
} M5StickV_t;

のようになっています.
このM5StickVStructの要素detection_resultは,配列なので

(defcstruct m5stickv-cstruct
  (is_exist :byte)
  (i2c_id :byte)
  (i2c_state :byte)
  (led_state :byte)
  (record_image :byte)
  (result_num :byte)
  (result object-detection-result-cstruct 8) 
  )

と定義するだけでいいようになっているといい気がしますが,
対応できていないようなので,手直ししておけるといい気がします.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants