PAnsiChar 與 String 轉換問題spcomm 元件 |
答題得分者是:aftcast
|
weiliching
初階會員 發表:53 回覆:78 積分:31 註冊:2003-12-27 發送簡訊給我 |
Dear 高手們:
我參考了 , http://delphi.ktop.com.tw/board.php?cid=169&fid=1015&tid=105074 修改了Spcomm 元件, 在傳送與接收都不會有問題 ,在傳送時.經過了PAnsiChar 傳送 但是我如果在傳送時改 成了"變數" 就會開始有問題 也就是 Var PAnsiChar Begin S:= ':01606495'; 我用Watch list 去看S的參數變化是ok的, 但是我改成 Var PAnsiChar Begin S:= PAnsiChar(':016' '06495'); 在去看S Waitch List 變化就會出問題 資料就會傳不過去 我發現到我的 問題是跟這大大題的問題一樣 http://delphi.ktop.com.tw/board.php?cid=30&fid=1498&tid=105543 但是因為我不能給他固定參數, 我的內容是一定要會變的String; 原始 程式 M_TenToChk 是自己寫的附程式,會把某Edit1.txt 轉換成String 相對需要的資料給我 主要功能是將他轉成2的補數. 16進位" 原始寫法如下: Var S:PAnsiChar; M_CHK :String; begin M_Chk := M_Public.TenToChk(StrTointDef(Edit1.Text,0)*10); s:= PAnsiChar(':0106' '0000' '0' M_Chk #13 #10); // s:= ':0106' '0000' '0' '06495' #13 #10;//改成這樣沒問題 Comm1.WriteCommData(s,Length(s));
附加檔案:5507a216a9060_4.JPG
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
please try as following:
var astr:AnsiString astr := ':0106' '0000' '0' M_Chk #13 #10; Comm1.WriteCommData(PAnsichar(astr),Length(astr));
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
weiliching
初階會員 發表:53 回覆:78 積分:31 註冊:2003-12-27 發送簡訊給我 |
感謝回覆~改成這樣就沒問題~ 但是弄不懂為何會這樣呢? 測試過很多方式~可能是對這些變數不瞭解~ 有參考過 PChar 與 String 知道儲存的方式不同. 能否有高手對這些參 至於AnsiString 與PAnsiChar,,,String 三個 差別.與? 一直也弄不清? ===================引 用 aftcast 文 章=================== please try as following: var astr:AnsiString astr := ':0106' '0000' '0' M_Chk #13 #10; Comm1.WriteCommData(PAnsichar(astr),Length(astr)); |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
|
weiliching
初階會員 發表:53 回覆:78 積分:31 註冊:2003-12-27 發送簡訊給我 |
謝謝aftcast String 在 d2009 版前是 AnsiString的別名,在 d2009(含)後是UnicodeString的別名。
AnsiString 是一個「容器」,裡面可以放字元,且容器裡存放的基本單位是二個byte。所謂的基本單位影響著UnicodeString 相關的函式對UnicodeString 的處理方式。 PChar 在 d2009前是一個指標(pointer),指向 AnsiString這個容器,相當於PAnsiChar ; 在 d2009後,則是指向UnicodeString容器。 何謂指標/針? (pointer) : 對於學c/c 語言的人理當都會懂。delphi也有指標,但很少人用心去懂、去用。請google查這方面的知識,假使你不太明白 pointer的話。但在這裡,簡單的說,它不是容器,它裡面放的只是一個記憶體(內存)的位址,該位址就是真的放資料(如,字串)的地方。(也就是容器的所在)。 中文字,用big5編碼時,是使用AnsiString容器來裝字元。即使big5的中文是2個bytes,但big5編碼下的英文部份依然是1個byte。而AnsiString的基本存放單位就是1個byte,所以專門拿來存這類的編碼。 中文字,用unicode (ucs2,utf16,但非utf8)的編碼時,因無論中文或是英文,都是占二個bytes,所以要用UnicodeString來裝,這樣字取用時,總是一次拿2個bytes出來。 windows 32 api 都是 c 語言寫的,所以許多的參數都是指標。所以幾乎是用PChar,或是PAnsiChar的型別來傳入給它用。由於你用的是rs232之類的通訊協定,照我多年經驗,都是處理以 1 byte為單位的一串資訊,即使是中文,通常也是big5編碼。故這種情形下,理當然用AnsiString來裝這些資料最恰當。 解說完精華,就讓我來說你的問題所在: 說來有點小複雜,但我有限的時間就稍粗的說。你的那行 ':0106' '0000' '0' M_Chk #13 #10; compiler大概是這樣處理的: 1/暫時建一個 string 容器,把那一堆字串加好後,放入這個暫時string裡。 2/ 因為你的變數是一個 PAnsiChar,所以compiler就為你建一個暫時的PAnsiChar的指標,並指向暫時的那個string容器 3/ 準備出錯了…… 當那一行程式執行完,跳至下一行時,那暫時的string容器會自動刪除 (否則就不會叫暫時),至於刪除的情形又可以分很多種情形,不過,你先別去了解,未來再說。你就當它會被清,僅管「有些時候,看起來似乎沒清,但千萬別心存僥倖」。 於是那個PAnsiChar所指的地方已經不是該有的內容。 解法: 我教你的作法就是,乖乖的把那些資串加入後放進一個AnsiString區域變數,這樣就可以保持它一直完好,直到跳出函式。而在它需要被使用指標送出時,再強轉型別即可。 給你的幾個建議: 1/ 儘量不要宣告PChar/PAnsiChar的型別變數,除非你真的很懂它。而真的需要它時,只要強轉型別即可。但記得D2009後,PChar 與 String (unicodestring)是一對的。 AnsiString與PAnsiChar是一對的。所謂的一對,就是你別試著把 String 轉 PAnsiChar 可能會出錯。除非你真的很了解編碼,不然就是用成對的來轉型。 2/ 計算字串長度,理當裡面放的是容器,而非指標。僅管delphi可能會幫你從指標想辦法找到容器,進一步算出長度,但這樣極度不可靠,要避免! 3/ 我以上所言,真的是句句重點,且是多年的心得,若可能,請務必每句都去了解我在說什麼。這樣應該就不會又忘記。 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |