全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3919
推到 Plurk!
推到 Facebook!

請教大大高手門,如何將unit1中的陣列傳到unit2中的func,算完再傳回結果

答題得分者是:hagar
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-08-03 00:38:51 IP:211.76.xxx.xxx 未訂閱
小弟寫一支程式如下 unit1: 利用VB MSCOMM元件做RS232通信,協定是MODBUS RTU, 送出一陣列值為 0.Function 03 1.Starting Address Hi 00 2.Starting Address Lo 6B 3.No. of Registers Hi 00 4.No. of Registers Lo 02 將陣列位址[0~4]值傳至unit2中的crc 函式,算完會傳回一個word的數值 5.CRC Hi xx 6.CRC Lo xx 將整個陣列傳至MSCOMM後 而傳回植為 0.Function 03 1.Byte Count 06 2.Register value Hi (108) 02 3.Register value Lo (108) 2B 4.Register value Hi (109) 00 5.Register value Lo (109) 00 須將陣列位址[2~5]傳至UNIT2中的HexToFloat函數,然後傳回一個Single型態的值 unit2: interface type pSingle = ^TSingle ; TSingle = record Case Integer Of 0: (AsSingle:Single); 1: (FirstHi,FirstLo,SecondHi,SecondLo:Byte); End; function CRC16(CRCData: array of Byte; Datalen: Integer):Word; implementation function HexToFloat(aryData: array of Byte; Datalen: Integer):Single; Var p : PSingle; S : Single ; begin S := 23 ; P := @S ; // 讓P 指向S 的位址(使用同一塊記憶體) // 或是 P.AsSingle := 23 ; // 可以不用S 變數,只用P來操作亦可。 // 逐個Byte 轉成16進位字串 P.FirstHi := aryData[2]; P.FirstLo := aryData[3]; P.SecondHi := aryData[4]; P.SecondLo := aryData[5]; end; function CRC16(CRCData: array of Byte; Datalen: Integer):Word; var CRC16Lo: Byte; CRC16Hi: Byte; SaveLo:Byte; SaveHi:Byte; GLo:Byte; GHi:Byte; i:Integer; Flag:Integer; begin CRC16Lo:=$ff; CRC16Hi:=$ff; GLo:=$01; GHi:=$a0; for i:=0 to Datalen -1 do begin CRC16Lo:=CRC16Lo xor CRCData[i]; for Flag :=0 to 7 do begin SaveLo:=CRC16Lo; SaveHi:=CRC16Hi; CRC16Hi:=CRC16Hi shr 1; CRC16Lo:=CRC16Lo shr 1; if (SaveHi and $01) = $01 then CRC16Lo:=CRC16Lo or $80; if (SaveLo and $01) = $01 then begin CRC16Hi:=CRC16Hi xor GHi; CRC16Lo:=CRC16Lo xor GLo; end; end; end; CRC16 := CRC16Lo * 256 CRC16Hi; end; end. 程式傳遞參數總是有問題,不知錯在那裡,煩請各為高手大大指導小弟,感恩萬分
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-08-03 01:06:12 IP:203.204.xxx.xxx 未訂閱
wychen57 你好
  程式傳遞參數總是有問題?
是那個函數有問題,你也沒說明,到底是什麼問題呢?底下僅針對貼上的程式內容,發現的問題說明如下:
1.function HexToFloat()要在宣告區先行宣告,才可讓別的元呼叫到
2.function HexToFloat()的 Datalen: Integer 這個好像沒必要
3.function HexToFloat()程式內容修改如下    function CRC16(CRCData: array of Byte):Word;
function HexToFloat(aryData: array of Byte):Single;    implementation    function HexToFloat(aryData: array of Byte):Single;
Var
  p : PSingle;
begin
//  S := 23 ;
  P := @Result ; // 讓P 指向S 的位址(使用同一塊記憶體)
  // 或是 P.AsSingle := 23 ; // 可以不用S 變數,只用P來操作亦可。      // 逐個Byte 轉成16進位字串
  P.FirstHi := aryData[2];
  P.FirstLo := aryData[3];
  P.SecondHi := aryData[4];
  P.SecondLo := aryData[5];
end;    PS:至於CRC16()除了運算部份之外程式架構,基本上沒有錯,只是DataLen參數
應該拿掉改由Length(CRCData)取得或用Low(CRCData) To High(CrcData)的方式
處理比較靈活。    function CRC16(CRCData: array of Byte):Word;
var
  CRC16Lo: Byte;
  CRC16Hi: Byte;
  SaveLo:Byte;
  SaveHi:Byte;
  GLo:Byte;
  GHi:Byte;
  i:Integer;
  Flag:Integer;
begin
  CRC16Lo:=$ff;
  CRC16Hi:=$ff;
  GLo:=$01;
  GHi:=$a0;
  for i:=Low(CRCData) to High(CRCData) do begin
    CRC16Lo:=CRC16Lo xor CRCData[i];
    for Flag :=0 to 7 do begin
      SaveLo:=CRC16Lo;
      SaveHi:=CRC16Hi;
      CRC16Hi:=CRC16Hi shr 1;
      CRC16Lo:=CRC16Lo shr 1;
      if (SaveHi and $01) = $01 then
        CRC16Lo:=CRC16Lo or $80;
      if (SaveLo and $01) = $01 then begin
        CRC16Hi:=CRC16Hi xor GHi;
        CRC16Lo:=CRC16Lo xor GLo;
      end;
    end;
  end;
  CRC16 := CRC16Lo * 256  CRC16Hi;
end;    
_______________________________________ 深藍的魚,祝您好運..........連連 發表人 - chance36 於 2004/08/03 01:08:18
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-08-07 09:11:12 IP:218.32.xxx.xxx 未訂閱
引言: wychen57 你好
  程式傳遞參數總是有問題?
是那個函數有問題,你也沒說明,到底是什麼問題呢?底下僅針對貼上的程式內容,發現的問題說明如下:
1.function HexToFloat()要在宣告區先行宣告,才可讓別的元呼叫到
2.function HexToFloat()的 Datalen: Integer 這個好像沒必要
3.function HexToFloat()程式內容修改如下    function CRC16(CRCData: array of Byte):Word;
function HexToFloat(aryData: array of Byte):Single;    implementation    function HexToFloat(aryData: array of Byte):Single;
Var
  p : PSingle;
begin
//  S := 23 ;
  P := @Result ; // 讓P 指向S 的位址(使用同一塊記憶體)
  // 或是 P.AsSingle := 23 ; // 可以不用S 變數,只用P來操作亦可。      // 逐個Byte 轉成16進位字串
  P.FirstHi := aryData[2];
  P.FirstLo := aryData[3];
  P.SecondHi := aryData[4];
  P.SecondLo := aryData[5];
end;    PS:至於CRC16()除了運算部份之外程式架構,基本上沒有錯,只是DataLen參數
應該拿掉改由Length(CRCData)取得或用Low(CRCData) To High(CrcData)的方式
處理比較靈活。    function CRC16(CRCData: array of Byte):Word;
var
  CRC16Lo: Byte;
  CRC16Hi: Byte;
  SaveLo:Byte;
  SaveHi:Byte;
  GLo:Byte;
  GHi:Byte;
  i:Integer;
  Flag:Integer;
begin
  CRC16Lo:=$ff;
  CRC16Hi:=$ff;
  GLo:=$01;
  GHi:=$a0;
  for i:=Low(CRCData) to High(CRCData) do begin
    CRC16Lo:=CRC16Lo xor CRCData[i];
    for Flag :=0 to 7 do begin
      SaveLo:=CRC16Lo;
      SaveHi:=CRC16Hi;
      CRC16Hi:=CRC16Hi shr 1;
      CRC16Lo:=CRC16Lo shr 1;
      if (SaveHi and $01) = $01 then
        CRC16Lo:=CRC16Lo or $80;
      if (SaveLo and $01) = $01 then begin
        CRC16Hi:=CRC16Hi xor GHi;
        CRC16Lo:=CRC16Lo xor GLo;
      end;
    end;
  end;
  CRC16 := CRC16Lo * 256  CRC16Hi;
end;    
_______________________________________ 深藍的魚,祝您好運..........連連 發表人 - chance36 於 2004/08/03 01:08:18
chance36大大您好,小弟程式寫得不好,你可能看不懂我的程式需求,crc16是要把陣列中特定長度的資料做crc運算並傳回呼叫者,而HEXTOFLOAT是把陣列中特定位置開始連續4BYTE轉成FLOAT資料(IEEE754格式),故兩者皆需指定需轉換之陣列長度或起始位置,而小弟就是不知怎麼寫才對,而且之前的問題就是陣列在這兩函數與主FORM之間傳遞失敗,每次傳回都傳錯誤資料(可能是傳值或傳址呼叫用錯了),煩請大大指點指點。
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-08-08 01:31:34 IP:203.204.xxx.xxx 未訂閱
wychen57 你好     可以描述一下,你想像中的狀況嗎?    怎麼呼叫? 傳什麼參數進去? 希望傳回什麼樣的資料回來呢?    _______________________________________ 深藍的魚,祝您好運..........連連
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-08-08 18:14:07 IP:203.70.xxx.xxx 未訂閱
引言: wychen57 你好 可以描述一下,你想像中的狀況嗎? 怎麼呼叫? 傳什麼參數進去? 希望傳回什麼樣的資料回來呢? _______________________________________ 深藍的魚,祝您好運..........連連
inbyte[0..1024],outbyte[0..7] as byte outbyte[0~7]=01,03,03,00,00,02,XX,yy crcdata=crc16(outbyte,5); xx= crcdata->Hibyte yy= crcdata->Lowbyte MSCOMM.Output=OutByte//將outbyte經mscomm送至設備 inbyte=MSCOMM.Input inbyte[3]開始為資料區,每4byte為一組,meter_val=HexToFloat(inbyte,i) i為要轉換之起始位置,現在問題就出在不論inbye->hextofloat or outbyte-->crc16,傳過去的都不是陣列元素的值,而是很奇怪的數值,所以始終無法算出正確數值,不知是我函數定義有問題還是傳遞的寫法有問題,大大能告訴我嗎,謝謝
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-08-09 00:02:01 IP:203.204.xxx.xxx 未訂閱
wychen57 你好
  參考下列程式,看符不符合需求?    type
  pSingle = ^TSingle ;
  TSingle = record
    Case Integer Of
      0: (AsSingle:Single);
      1: (FirstHi,FirstLo,SecondHi,SecondLo:Byte);
  End;      TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  // 宣告位置在兒,別的單元才可以呼叫得到
  // 或是將這兩函式放到獨立公用函式的單元檔中
  function CRC16(CRCData: array of Byte; Datalen: Integer):Word;
  function HexToFloat(aryData: array of Byte; Datalen: Integer):Single;    var
  Form1: TForm1;    implementation    {$R *.DFM}    function HexToFloat(aryData: array of Byte; Datalen: Integer):Single;
Var
  p : PSingle;
begin
  P := @Result ;
  P.FirstHi  := aryData[Datalen];
  P.FirstLo  := aryData[Datalen 1];
  P.SecondHi := aryData[Datalen 2];
  P.SecondLo := aryData[Datalen 3];
end;    function CRC16(CRCData: array of Byte; Datalen: Integer):Word;
var
  CRC16Lo: Byte;
  CRC16Hi: Byte;
  SaveLo:Byte;
  SaveHi:Byte;
  GLo:Byte;
  GHi:Byte;
  i:Integer;
  Flag:Integer;
begin
  CRC16Lo:=$ff;
  CRC16Hi:=$ff;
  GLo:=$01;
  GHi:=$a0;
  for i:=0 to Datalen -1 do begin
    CRC16Lo:=CRC16Lo xor CRCData[i];
    for Flag :=0 to 7 do begin
      SaveLo:=CRC16Lo;
      SaveHi:=CRC16Hi;
      CRC16Hi:=CRC16Hi shr 1;
      CRC16Lo:=CRC16Lo shr 1;
      if (SaveHi and $01) = $01 then
        CRC16Lo:=CRC16Lo or $80;
      if (SaveLo and $01) = $01 then begin
        CRC16Hi:=CRC16Hi xor GHi;
        CRC16Lo:=CRC16Lo xor GLo;
      end;
    end;
  end;
  CRC16 := CRC16Lo * 256  CRC16Hi;
end;    procedure TForm1.BitBtn1Click(Sender: TObject);
Var
  inbyte : Array[0..1024] Of Byte;
  outbyte: Array[0..7] Of byte;
  xx,yy : Byte ;
  crcData : Word ;
  meter_val : Single ;
begin
  outbyte[0] := 01;
  outbyte[1] := 03;
  outbyte[2] := 03;
  outbyte[3] := 00;
  outbyte[4] := 00;
  outbyte[5] := 02;
  CrcData := crc16( outbyte , 6 );
  // 算出CRC值後再寫入到outbyte[6..7]
  outbyte[6] := Trunc(crcData/256) ;
  outbyte[7] := (crcData Mod 256);
//  ShowMessage(IntToStr(Integer(crcdata)));      InByte[3] := $00;
  InByte[4] := $00;
  InByte[5] := $2b;
  InByte[6] := $43;      InByte[7] := $00;
  InByte[8] := $00;
  InByte[9] := $2c;
  InByte[10] := $43;
  // 以上是假設資料,你應該改成這樣
  MSCOMM.Output=OutByte;//將outbyte經mscomm送至設備
  inbyte=MSCOMM.Input;      meter_val := HexToFloat(InByte, 3);
  ShowMessage(FloatToStr(meter_val));      meter_val := HexToFloat(InByte, 7);
  ShowMessage(FloatToStr(meter_val));    end;    end.
_______________________________________ 深藍的魚,祝您好運..........連連
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-08-11 11:53:45 IP:61.66.xxx.xxx 未訂閱
chance36大大你好 小弟照您的程式宣告依然無法跨unit呼叫,煩請大大再指導一下,感恩。mainform與unitfunc宣告如下 unitFunc: unit UnitFunc; interface type pSingle = ^TSingle ; TSingle = record Case Integer Of 0: (AsSingle:Single); 1: (FirstHi,FirstLo,SecondHi,SecondLo:Byte); End; public function CRC16(CRCData: array of Byte; Datalen: Integer):Word; function HexToFloat(aryData: array of Byte; Datalen: Integer):Single; End; implementation MainForm宣告如下 unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, OleCtrls, MSCommLib_TLB, UnitFunc; type TfrmMain = class(TForm) Edit1: TEdit; Edit2: TEdit; btnSend: TButton; btnRecive: TButton; MSComm: TMSComm; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var frmMain: TfrmMain; implementation // uses UnitFunc; {$R *.dfm}
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-08-11 13:52:29 IP:61.66.xxx.xxx 未訂閱
CrcData := crc16( outbyte , 6 ); ^^^^^出現"undeclared identifier crc16" // 算出CRC值後再寫入到outbyte[6..7] outbyte[6] := Trunc(crcData/256) ; outbyte[7] := (crcData Mod 256); // ShowMessage(IntToStr(Integer(crcdata))); MSCOMM.Output=OutByte;//將outbyte經mscomm送至設備 ^^^^^^^^^^^^^^^^^^^^^^^^^^^出現"Incompatible 'OleVariant' and 'array'" inbyte=MSCOMM.Input;[/green] ^^^^^^^^^^^^^^^^^^^^^^^^^^^出現"Incompatible 'OleVariant' and 'array'"
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-08-11 14:49:04 IP:211.20.xxx.xxx 未訂閱
CrcData := crc16( outbyte , 6 ); ^^^^^出現"undeclared identifier crc16"
unit UnitFunc;    interface
type 
  pSingle = ^TSingle ;
  TSingle = record
    Case Integer Of
      0: (AsSingle:Single);
      1: (FirstHi,FirstLo,SecondHi,SecondLo:Byte);
  End;
  //public  <============== 移除
  function CRC16(CRCData: array of Byte; Datalen: Integer):Word;
  function HexToFloat(aryData: array of Byte; Datalen: Integer):Single;
  //End;    <============== 移除    implementation    
MSCOMM.Output=OutByte;//將outbyte經mscomm送至設備 ^^^^^^^^^^^^^^^^^^^^^^^^^^^出現"Incompatible 'OleVariant' and 'array'" inbyte=MSCOMM.Input; ^^^^^^^^^^^^^^^^^^^^^^^^^^^出現"Incompatible 'OleVariant' and 'array'" MSCOMM.output的型態為'OleVariant'而outbyte為Array Of Byte兩者不相容 一般通訊API皆以PChar為參數型態,所以outbyte及inByte應該改成PChar型態看看。(MSCOMM我並沒用過,實際要怎麼使用我也不清楚) [/green] _______________________________________ 深藍的魚,祝您好運..........連連
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-08-11 15:50:52 IP:61.66.xxx.xxx 未訂閱
MSCOMM.output的型態為'OleVariant'而outbyte為Array Of Byte兩者不相容 一般通訊API皆以PChar為參數型態,所以outbyte及inByte應該改成PChar型態看看。(MSCOMM我並沒用過,實際要怎麼使用我也不清楚) 那請問要如何定義,pchar跟array要怎麼轉換,或pchar要怎麼巷array一樣可以逐bytpe塞資料(如outbyte),或如何取單一byte資料(如inbyte),不然crc16跟hectofloat就無法使用啦,而且剛把程式改成如下所示 var pInByte : pchar; pOutByte : pchar; pOutByte := @OutByte; MSCOMM.Output := pOutByte;//將outbyte經mscomm送至設備 出現"incompatible 'OleVariant' and 'PAnsiChar'"喔
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-08-11 18:40:45 IP:202.39.xxx.xxx 未訂閱
引言: CrcData := crc16( outbyte , 6 ); ^^^^^出現"undeclared identifier crc16"
unit UnitFunc;    interface
type 
  pSingle = ^TSingle ;
  TSingle = record
    Case Integer Of
      0: (AsSingle:Single);
      1: (FirstHi,FirstLo,SecondHi,SecondLo:Byte);
  End;
  //public  <============== 移除
  function CRC16(CRCData: array of Byte; Datalen: Integer):Word;
  function HexToFloat(aryData: array of Byte; Datalen: Integer):Single;
  //End;    <============== 移除    implementation    
MSCOMM.Output=OutByte;//將outbyte經mscomm送至設備 ^^^^^^^^^^^^^^^^^^^^^^^^^^^出現"Incompatible 'OleVariant' and 'array'" inbyte=MSCOMM.Input;
^^^^^^^^^^^^^^^^^^^^^^^^^^^出現"Incompatible 'OleVariant' and 'array'" MSCOMM.output的型態為'OleVariant'而outbyte為Array Of Byte兩者不相容 一般通訊API皆以PChar為參數型態,所以outbyte及inByte應該改成PChar型態看看。(MSCOMM我並沒用過,實際要怎麼使用我也不清楚) [/green] _______________________________________ 深藍的魚,祝您好運..........連連
關於 OleVariant 與 Array of Byte 的部份, 也許這篇幫得上忙: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=35466 -- 向 KTop 的弟兄們致敬!
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-08-11 21:40:55 IP:211.76.xxx.xxx 未訂閱
引言: 關於 OleVariant 與 Array of Byte 的部份, 也許這篇幫得上忙: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=35466 -- 向 KTop 的弟兄們致敬! [img]http://www.sweetbaby.net/~hagar/good.bmp
感謝hagar大大指教,但那只有輸出給mscomm,沒有從mscomm讀入再轉回array的範例,煩請大大指導,謝謝
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-08-12 08:19:48 IP:202.39.xxx.xxx 未訂閱
參考這篇試試: http://groups.google.com/groups?hl=zh-TW&lr=&ie=UTF-8&th=44fc6498863d55a7&rnum=33
type
  TArrayOfByte = array of Byte;    procedure VariantToArrayOfByte(const V: OleVariant;
                               out A: TArrayOfByte);    var
  L: Integer;
  P: Pointer;    begin
  Assert(VarType(V) = varByte or varArray);
  Assert(VarArrayDimCount(V) = 1);      L := VarArrayHighBound(V, 1) - VarArrayLowBound(V, 1)   1;      SetLength(A, L);
  P := VarArrayLock(V);
  try
    Move(P^, Pointer(A)^, L);
  finally
    VarArrayUnlock(V);
  end;
end;    //The complementary procedure would be:    procedure ArrayOfByteToVariant(const A: TArrayOfByte;
                               out V: OleVariant);    var
  L: Integer;
  P: Pointer;    begin
  L := Length(A);
  V := VarArrayCreate([0, L - 1], varByte);      P := VarArrayLock(V);
  try
    Move(Pointer(A)^, P^, L);
  finally
    VarArrayUnlock(V);
  end;
end;
-- 向 KTop 的弟兄們致敬!
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-08-12 10:10:55 IP:61.66.xxx.xxx 未訂閱
hagar大大你好,小弟還是將完整程式碼貼出給站上高手大大看好了,小弟的程式區分主表單程序單元(MainForm & UnitProg),所有副程式皆放在unitprog中 主表單如下 unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, OleCtrls, MSCommLib_TLB, UnitFunc; type TArrayOfByte = array of byte; TfrmMain = class(TForm) Edit1: TEdit; Edit2: TEdit; btnSend: TButton; btnRecive: TButton; MSComm: TMSComm; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure VariantToArrayOfByte(const V: OleVariant;out A: TArrayOfByte); // [Error] Main.pas(24): Unsatisfied forward or external declaration: 'TfrmMain.VariantToArrayOfByte' procedure ArrayOfByteToVariant(const A: TArrayOfByte;out V: OleVariant); // [Error] Main.pas(25): Unsatisfied forward or external declaration: 'TfrmMain.ArrayOfByteToVariant' private { Private declarations } public { Public declarations } end; var frmMain: TfrmMain; implementation // uses UnitFunc; {$R *.dfm} procedure VariantToArrayOfByte(const V: OleVariant;out A: TArrayOfByte); var L: Integer; P: Pointer; begin Assert(VarType(V) = varByte or varArray); Assert(VarArrayDimCount(V) = 1); L := VarArrayHighBound(V, 1) - VarArrayLowBound(V, 1) 1; SetLength(A, L); P := VarArrayLock(V); try Move(P^, Pointer(A)^, L); finally VarArrayUnlock(V); end; end; //The complementary procedure would be: procedure ArrayOfByteToVariant(const A: TArrayOfByte;out V: OleVariant); var L: Integer; P: Pointer; begin L := Length(A); V := VarArrayCreate([0, L - 1], varByte); P := VarArrayLock(V); try Move(Pointer(A)^, P^, L); finally VarArrayUnlock(V); end; end; procedure TfrmMain.FormCreate(Sender: TObject); var lblary : array Of Pointer; //a: array[0..7] of Byte; //b: array[0..1] of Byte; OutByte: Array[0..10] Of Byte ; inbyte : Array[0..1024] Of Byte; crcData : Word ; StrByte : OleVariant; Meter_Val : Single ; begin mscomm.CommPort:=1; mscomm.Settings:= '9600,n,8,1'; mscomm.InputMode:=1; mscomm.PortOpen:= true; SetLength(lblary, 6); lblary[0]:= Edit1; lblary[1]:= Edit2; lblary[2]:= Edit3; lblary[3]:= Edit4; lblary[4]:= Edit5; lblary[5]:= Edit6; //TButton(oa[1]).Caption := 'xxxxx'; outbyte[0] := $01; outbyte[1] := $03; outbyte[2] := $00; outbyte[3] := $1A; outbyte[4] := $00; outbyte[5] := $02; CrcData := crc16( outbyte , 6 ); // 算出CRC值後再寫入到outbyte[6..7] outbyte[6] := Trunc(crcData/256) ; outbyte[7] := (crcData Mod 256); edit3.Text:= IntToStr(outbyte[6]); edit4.Text:= IntToStr(outbyte[7]); InByte[3] := $00; InByte[4] := $00; InByte[5] := $2b; InByte[6] := $43; InByte[7] := $00; InByte[8] := $00; InByte[9] := $2c; InByte[10] := $43; // 以上是假設資料,你應該改成這樣 ArrayOfByteToVariant(OutByte,StrByte);//將outbyte經mscomm送至設備 //出現 [Error] Main.pas(131): Incompatible types: 'Array' and 'TArrayOfByte' MSCOMM.Output := StrByte; StrByte := MSCOMM.Input; VariantToArrayOfByte(StrByte,InByte); // [Error] Main.pas(134): Types of actual and formal var parameters must be identical meter_val := HexToFloat(InByte, 3); edit1.Text:= FloatToStr(meter_val); //ShowMessage(FloatToStr(meter_val)); meter_val := HexToFloat(InByte, 7); edit2.Text:= FloatToStr(meter_val); //ShowMessage(FloatToStr(meter_val)); end; procedure TfrmMain.Button1Click(Sender: TObject); begin mscomm.PortOpen:=false; close; end; end. 程序單元如下 unit UnitFunc; interface uses SysUtils, Variants; type pSingle = ^TSingle ; TSingle = record Case Integer Of 0: (AsSingle:Single); 1: (FirstHi,FirstLo,SecondHi,SecondLo:Byte); End; function CRC16(CRCData: array of Byte; Datalen: Integer):Word; function HexToFloat(aryData: array of Byte; Datalen: Integer):Single; function Str(ArrayData: array of Byte):string; implementation function HexToFloat(aryData: array of Byte; Datalen: Integer):Single; Var p : PSingle; begin P := @Result; P.FirstHi := aryData[Datalen]; P.FirstLo := aryData[Datalen 1]; P.SecondHi := aryData[Datalen 2]; P.SecondLo := aryData[Datalen 3]; end; function CRC16(CRCData: array of Byte; Datalen: Integer):Word; var CRC16Lo: Byte; CRC16Hi: Byte; SaveLo:Byte; SaveHi:Byte; GLo:Byte; GHi:Byte; i:Integer; Flag:Integer; begin CRC16Lo:=$ff; CRC16Hi:=$ff; GLo:=$01; GHi:=$a0; for i:=0 to Datalen -1 do begin CRC16Lo:=CRC16Lo xor CRCData[i]; for Flag :=0 to 7 do begin SaveLo:=CRC16Lo; SaveHi:=CRC16Hi; CRC16Hi:=CRC16Hi shr 1; CRC16Lo:=CRC16Lo shr 1; if (SaveHi and $01) = $01 then CRC16Lo:=CRC16Lo or $80; if (SaveLo and $01) = $01 then begin CRC16Hi:=CRC16Hi xor GHi; CRC16Lo:=CRC16Lo xor GLo; end; end; end; CRC16 := CRC16Lo * 256 CRC16Hi; end; function Str(ArrayData: array of Byte):String; var i: Integer; Str: string; begin Str := ''; for i := Low(ArrayData) to High(ArrayData) do Str := Str IntToStr(ArrayData[i]); end; end. 其中VariantToArrayOfByte & ArrayOfByteToVariant要改成function 我需要的是類似 mscomm.output :=ArrayOfByteToVariant(OutByte); StrByte := mscomm.input; InByte := VariantToArrayOfByte(StrByte); 大大您能了解我的問題嗎,煩請不吝指導,感恩萬分 發表人 -
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#15 引用回覆 回覆 發表時間:2004-08-18 17:34:28 IP:61.66.xxx.xxx 未訂閱
煩請大大們指導一下,小弟的問題差這一點點就能解決了,感謝指導呀
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#16 引用回覆 回覆 發表時間:2004-08-18 20:39:08 IP:202.39.xxx.xxx 未訂閱
您要的是這樣?
type
  TArrayOfByte = array of Byte;    function VariantToArrayOfByte(const V: OleVariant): TArrayOfByte;
var
  L: Integer;
  P: Pointer;
begin
  Assert(VarType(V) = varByte or varArray);
  Assert(VarArrayDimCount(V) = 1);      L := VarArrayHighBound(V, 1) - VarArrayLowBound(V, 1)   1;      SetLength(Result, L);
  P := VarArrayLock(V);
  try
    Move(P^, Pointer(Result)^, L);
  finally
    VarArrayUnlock(V);
  end;
end;    function ArrayOfByteToVariant(const A: TArrayOfByte): OleVariant;
var
  L: Integer;
  P: Pointer;
begin
  L := Length(A);
  Result := VarArrayCreate([0, L - 1], varByte);      P := VarArrayLock(Result);
  try
    Move(Pointer(A)^, P^, L);
  finally
    VarArrayUnlock(Result);
  end;
end;
-- 歡迎光臨 KTop 研究苑!
wychen57
一般會員


發表:32
回覆:77
積分:21
註冊:2003-10-04

發送簡訊給我
#17 引用回覆 回覆 發表時間:2004-08-18 22:41:23 IP:210.244.xxx.xxx 未訂閱
正是要這個,感恩 順便請教大大,你都用啥方式做
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#18 引用回覆 回覆 發表時間:2004-08-19 08:44:01 IP:202.39.xxx.xxx 未訂閱
小弟用的是 TurboPower Async Professional 套件裡的 TApdComport 元件  -- < src="http://www.sweetbaby.net/~hagar/good.bmp">歡迎光臨 KTop 研究苑!
neopasia
一般會員


發表:0
回覆:1
積分:0
註冊:2004-12-21

發送簡訊給我
#19 引用回覆 回覆 發表時間:2005-01-16 10:01:27 IP:219.159.xxx.xxx 未訂閱
你们好,我根据你们的帖子写了一段代码,我把crc校验的部分省去了(就是说我发送的直接是计算好的crc校验码),现在不知道为什么,设备返回来的数据老是不正常?请教一下,应该是哪方面的问题?
系統時間:2024-09-06 13:25:24
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!