下列這個C的struct宣告怎麼改成Delphi的record ? |
答題得分者是:syntax
|
greatcat
一般會員 發表:7 回覆:9 積分:3 註冊:2005-01-12 發送簡訊給我 |
[code cpp] typedef struct _REPORT_KEY_DATA_RPC_STATE { char rsvrd1[4]; unsigned char nb_user_changes: 3; unsigned char nb_vendor_resets: 3; unsigned char type_code: 2; unsigned char region_mask; unsigned char rpc_scheme; char rsvrd2; } REPORT_KEY_DATA_RPC_STATE; [/code] 小弟最近在寫DVD ODD region的檢查程式,要用到MSDN內,VC宣告了一個有點奇怪的struck 上列的struct,會把nb_user_changes ,nb_vendor_resets, type_code宣告在同一個byte內, nb_user_changes 用bit 0~2 nb_vendor_resets用bit 3~5 unsigned char type_code用bit 6~7 Delphi / pascal有相對應的方法可以宣告嗎?
------
我喵故我在 |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
Delphi 在 record 上 並不支援 bit 格式的指定方式
但可以使用 case 的方式宣告,使其共用記憶體空間,而你使用該欄位時,要控制只使用對應的 bit [code delphi] REPORT_KEY_DATA_RPC_STATE_st = record rsvrd1: array[0..13] of Byte; case Integer of 0: (nb_user_changes: Byte); 1: (nb_vendor_resets: Byte); 2: (type_code: Byte); region_mask: Byte; rpc_scheme: Byte; rsvrd2: Byte; end; [/code] ===================引 用 greatcat 文 章=================== [code cpp] typedef struct _REPORT_KEY_DATA_RPC_STATE { char rsvrd1[4]; unsigned char nb_user_changes: 3; unsigned char nb_vendor_resets: 3; unsigned char type_code: 2; unsigned char region_mask; unsigned char rpc_scheme; char rsvrd2; } REPORT_KEY_DATA_RPC_STATE; [/code] 小弟最近在寫DVD ODD region的檢查程式,要用到MSDN內,VC宣告了一個有點奇怪的struck 上列的struct,會把nb_user_changes ,nb_vendor_resets, type_code宣告在同一個byte內, nb_user_changes 用bit 0~2 nb_vendor_resets用bit 3~5 unsigned char type_code用bit 6~7 Delphi / pascal有相對應的方法可以宣告嗎?
編輯記錄
syntax 重新編輯於 2007-12-12 23:56:45, 註解 無‧
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
突發奇想, 一個有點麻煩的作法, 提供給你參考
(1)定義一個 record , TRec (2)宣告一個介面, IRec (3)使用一個物件來實作介面, TRecIMPL (4)在介面方法中, 處理 bit fields (5)使用PRec來存取資料, 以確保作用在同一筆資料. 程式碼謹供參考... [code delphi] unit fMain; interface uses Classes, Forms, Controls, SysUtils, StdCtrls; type { TRec } PRec = ^TRec; TRec = packed record rsvrd1: array[0..3] of Char;//Reserved_1 state: Byte; //內含那三個 bit fields region_mask: Byte; rpc_scheme: Byte; rsvrd2: Char; //Reserved_2 end; { IRec } IRec = interface function get_nb_user_changes: Byte; function get_nb_vendor_resets: Byte; function get_region_mask: Byte; function get_rpc_scheme: Byte; function get_type_code: Byte; procedure set_nb_user_changes(const Value: Byte); procedure set_nb_vendor_resets(const Value: Byte); procedure set_region_mask(const Value: Byte); procedure set_rpc_scheme(const Value: Byte); procedure set_type_code(const Value: Byte); property nb_user_changes: Byte read get_nb_user_changes write set_nb_user_changes; property nb_vendor_resets: Byte read get_nb_vendor_resets write set_nb_vendor_resets; property type_code: Byte read get_type_code write set_type_code; property region_mask: Byte read get_region_mask write set_region_mask; property rpc_scheme: Byte read get_rpc_scheme write set_rpc_scheme; end; { TRecIMPL } TRecIMPL = class(TInterfacedObject, IRec) protected P: PRec; function get_nb_user_changes: Byte; function get_nb_vendor_resets: Byte; function get_region_mask: Byte; function get_rpc_scheme: Byte; function get_type_code: Byte; procedure set_nb_user_changes(const Value: Byte); procedure set_nb_vendor_resets(const Value: Byte); procedure set_region_mask(const Value: Byte); procedure set_rpc_scheme(const Value: Byte); procedure set_type_code(const Value: Byte); public constructor Create(Rec: PRec); end; { TForm1 } TForm1 = class(TForm) Button1: TButton; ListBox1: TListBox; procedure Button1Click(Sender: TObject); private function dd(Rec: PRec): IRec; end; var Form1: TForm1; //------------------------------------------------------------------------------ implementation {$R *.dfm} { TRecIMPL } constructor TRecIMPL.Create(Rec: PRec); begin inherited Create; P := Rec; end; //gets function TRecIMPL.get_nb_user_changes: Byte; begin Result := P.state and $07; end; function TRecIMPL.get_nb_vendor_resets: Byte; begin Result := (P.state shr 3) and $07;end; function TRecIMPL.get_type_code: Byte; begin Result := P.state shr 6; end; function TRecIMPL.get_region_mask: Byte; begin Result := P.region_mask; end; function TRecIMPL.get_rpc_scheme: Byte; begin Result := P.rpc_scheme; end; //sets procedure TRecIMPL.set_region_mask(const Value: Byte);begin P.region_mask := Value; end; procedure TRecIMPL.set_rpc_scheme(const Value: Byte); begin P.rpc_scheme := Value; end; procedure TRecIMPL.set_nb_user_changes(const Value: Byte); begin //$07 = 00000111b, $F8 = 11111000b //分解動作 P.state := P.state and $F8; //清除 P.state := P.state or (Value and $07);//設定 end; procedure TRecIMPL.set_nb_vendor_resets(const Value: Byte); begin //$07 = 00000111b, $C7 = 11000111b //分解動作 P.state := P.state and $C7; //清除 P.state := P.state or ((Value and $07) shl 3);//設定 end; procedure TRecIMPL.set_type_code(const Value: Byte); begin //$03 = 00000011b, $3F = 00111111b P.state := P.state and $3F; //清除 P.state := P.state or ((Value and $03) shl 6);//設定 end; //------------------------------------------------------------------------------ { TForm1 } function TForm1.dd(Rec: PRec): IRec; begin Result := TRecIMPL.Create(Rec);//傳回介面 end; procedure TForm1.Button1Click(Sender: TObject); var r: TRec; i: IRec; begin FillChar(r, SizeOf(r), 0);//清除 //------------------------ i := dd(@r); try i.nb_user_changes := 1; i.nb_vendor_resets := 2; i.type_code := 3; i.region_mask := 4; i.rpc_scheme := 5; ListBox1.Clear; ListBox1.Items.Add(IntToStr(i.nb_user_changes)); ListBox1.Items.Add(IntToStr(i.nb_vendor_resets)); ListBox1.Items.Add(IntToStr(i.type_code)); ListBox1.Items.Add(IntToStr(i.region_mask)); ListBox1.Items.Add(IntToStr(i.rpc_scheme)); finally i := nil; end; end; end. [/code]
編輯記錄
jow 重新編輯於 2007-12-12 23:37:14, 註解 無‧
|
greatcat
一般會員 發表:7 回覆:9 積分:3 註冊:2005-01-12 發送簡訊給我 |
|
Coffee
版主 發表:31 回覆:878 積分:561 註冊:2006-11-15 發送簡訊給我 |
search records, and select "Variant parts in records"
===================引 用 greatcat 文 章=================== 喔~原來delphi有 record case這麼奇怪的隱藏用法.連help都找不到. 感謝各位的幫助, 我把DVD region detect的delphi範例傳到會員創作發表區囉.
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。 為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。 在引述到我的文時自然會儘量替各位想辦法,謝謝大家! |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |