ActiveBasicのバグと思われる不具合を発見された方は、こちらから知らせていただけると助かります。
-
KICO
- 記事: 57
- 登録日時: 2005年12月13日(火) 17:42
#1
投稿記事
by KICO »
何時も、お世話に成っています。
コード: 全て選択
Dim str As String
Dim size As Long
str = ZeroString(20)
size = GetDWord(str - SizeOf(DWord))
Ver3.13では、size = 20 と取得出来ますが、
Ver4.24では、エラー:「型が違います」 と、成り
(size = GetDWord(StrPtr(str) - SizeOf(DWord))とすれば、size = 20 と取得出来ます。)
Ver5cp3 及び、Ver5β6では、エラー:「"Operator -" は定義されていません。」 と、成ります。
(size = GetDWord(StrPtr(str) - SizeOf(DWord))とすれば、エラーには成りませんが、
size = 20 と取得出来ません。)
http://dev.activebasic.com/dai/?m=200607 (CStringクラス)
仕様が変わったのでしょうか?
宜しくお願いします。
-
OverTaker
- 記事: 231
- 登録日時: 2005年5月31日(火) 17:14
- お住まい: 茨城県
#2
投稿記事
by OverTaker »
こんにちは、OverTakerです。
KICOさんの察した通り、Stringの仕様が変更になったため、このようなことが起こります。
コード: 全て選択
Dim str As String
Dim size As Long
str = ZeroString(20)
size = GetDWord(str - SizeOf(DWord))
このコードはちょっと意外ですね。以前String型は、文字列の先頭の前にサイズを表していたので、このような荒技的なコードが使用できました。
しかし、現在は
Wikiで見ると分かりますが、String型はコンパイラ定義ではなく、Stringクラスとして、ライブラリで提供されるようになりました。これにより、以前とは違ったStringクラスとなりましたので、その方法は使用できません。
文字列のサイズを取得する方法としては、以下の方法があります。
コード: 全て選択
#console
Dim s As String
s = "ActiveBasic"
Print Len(s)
Print lstrlen(s)
Print s.Length
Sleep(1000)
他にもあるかもしれませんが、一番下のやり方はStringクラスで使用することができます。上の2つは、以前のコンパイラでも使用することができます。
現在のStringクラスはまだ完全ではありませんので、s.Lengthに値が書き込めてしまうのですが、誤作動を起こすのでそのようなコードは書かないようにしてください。
-
KICO
- 記事: 57
- 登録日時: 2005年12月13日(火) 17:42
#3
投稿記事
by KICO »
OverTaker様、ありがとう御座います。
以前String型は、文字列の先頭の前にサイズを表していたので、このような荒技的なコードが使用できました。
しかし、現在はWikiで見ると分かりますが、String型はコンパイラ定義ではなく、Stringクラスとして、ライブラリで提供されるようになりました。これにより、以前とは違ったStringクラスとなりましたので、その方法は使用できません。
それでVer5以降は使用できなかったのですね。(バグではなかったのですね、失礼致しました。)
このコードはちょっと意外ですね。…
String型文字列をポインタ渡しで受け取った場合、lstrlen ではEOS(End Of String)までの
バイト数は得られますが、ZeroString で確保したバイト数は、Len では得られないので
GetDWord を使用しました。
コード(Ver3.13, Ver4.24 仕様) [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]Dim str As String
Dim buf As BytePtr
Dim byt[MAX_PATH-1] As Byte
Dim a As Long
Dim b As Long
Dim c As Long
Dim d As Long
str = ZeroString(20)
buf = " "
a=test(str)
b=Len(str)
c=test(buf)
d=test(byt)
Debug
Function test(lpStr As BytePtr) As Long
Dim str As String
str="Test": test=Len(str)
If HeapSize(GetProcessHeap(), 0, lpStr-4)<>-1 Then
'String Type
If GetDWord(lpStr-4)<test Then Exit Function
SetDWord(lpStr-4, test) 'サイズ書き換え
End If
lstrcpy(lpStr, str)
End Function
HeapSize関数に関する質問は、
http://www.activebasic.com/forum/viewtopic.php?t=1678
「プログラミング質問板」で質問させて頂いていますので、そちらの方も宜しくお願い致します。
-
イグトランス
- 記事: 899
- 登録日時: 2005年5月31日(火) 17:59
- お住まい: 東京都
-
連絡する:
#4
投稿記事
by イグトランス »
そもそもBytePtr型の引数を受け取るところに,String型の変数が渡された場合を処理しようということで,無理が生じてしまいます。
私だったら,多くのWindows APIの関数がそうであるようにBytePtr型の引数と,その大きさを示す変数を取る関数を作り,
別途String型を受け取る版の関数を作ります。
(GetWindowTextとGetWindowTextStrのように)
-
KICO
- 記事: 57
- 登録日時: 2005年12月13日(火) 17:42
#5
投稿記事
by KICO »
イグトランス (egtra)様、ありがとう御座います。
そもそもBytePtr型の引数を受け取るところに,String型の変数が渡された場合を処理しようということで,無理が生じてしまいます。
呼び出し側のデータ型のチェックが出来れば、一つの関数で使い分けしなくて良いのでやっていましたが、無理な様ですね。
「呼び出し側のデータ型のチェック」に、ついて 「プログラミング質問板」で、質問させて頂きます。
宜しくお願い致します。