ByteStrを引数に取るプロシージャへの引数の与え方でエラー

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
Namu
記事: 2
登録日時: 2005年7月23日(土) 10:58

ByteStrを引数に取るプロシージャへの引数の与え方でエラー

#1 投稿記事 by Namu »

今後ActiveBasicを使わさせてもらおうと,いろいろ試しています。

ByteStrを引数に取るプロシージャを作成し,それを呼び出す際,
引数の与え方によってエラーが発生してしまいます。

下記のプログラムサンプルをご覧ください。

引数としてStrPtr()関数を直接使用すると,「無効な識別子」と
叱られます。
でも,一度BytePtr型変数に代入してからだと叱られません。

何か記述方法を間違っているのでしょうか?
(間違っているとしたら,プロシージャの宣言部分だろうと思う
のですが...)

コード: 全て選択


#console

Main()

Sub PrintString(ByRef myString As BytePtr)
    MsgBox 0, myString, "Print String"
End Sub

Sub Main ()
    Dim myString As String
    myString = ZeroString(100)
    lstrcpy(StrPtr(myString), "Message")

    '下記記述だと「StrPtr(myString)が無効な識別子」と叱られる
    PrintString(StrPtr(myString))

    '下記記述だとOK。なぜ?
    Dim myStringPtr As BytePtr
    myStringPtr = StrPtr(myString)
    PrintString(myStringPtr)
End Sub
Toshi
記事: 98
登録日時: 2005年7月19日(火) 19:47
お住まい: 山形県
連絡する:

#2 投稿記事 by Toshi »

引数が(ByRef myString As BytePtr)の場合は
「BytePtr型のポインタ参照」となり、
何か変数を渡さなければならない為
StrPtr()では渡せなくなってしまいます。
下のエラーにならない例では、
BytePtr型のmyStringPtrをポインタ参照しているので
きちんと渡せています。

PrintString関数の引数をByValにすれば変数でない値も渡せるので、
この方法を使えば良いと思います。
この場合も、下のmyStringPtrは結局は値参照なので
エラーになりません。

コード: 全て選択


#console

Main()

Sub PrintString(ByVal myString As BytePtr)
    MsgBox 0, myString, "Print String"
End Sub

Sub Main ()
    Dim myString As String
    myString = ZeroString(100)
    lstrcpy(StrPtr(myString), "Message")

    PrintString(StrPtr(myString))

    Dim myStringPtr As BytePtr
    myStringPtr = StrPtr(myString)
    PrintString(myStringPtr)
End Sub
ゲスト

Re: ByteStrを引数に取るプロシージャへの引数の与え方でエラー

#3 投稿記事 by ゲスト »

こんな関数に

コード: 全て選択

Sub Proc(ByRef Num As Long)
	Num = 1
End Sub
Proc(0)という呼び出しはできないというのはなんとなくわかると思います。
引数が関数の戻り値の場合もこれと同じ扱いを受けます。

Naruさんの例では実際には変数の中身を書き換えてはいませんが、ByRefを指定すると書き換えられるものとして扱われるのでNaruさんのコードもエラーになってしまいます。

しかし抜け穴があってPrintString(ByVal VarPtr(myString))とすればコンパイルできるんですね。
どういうことかというとByRefの引数はByVal VarPtr()と等価になります。
つまりPrintString(myStringPtr)という呼び出しはPrintString(ByVal VarPtr(myStringPtr))と同じになります。
String型は表面上BytePtrと同じように文字列をさすポインタからなっているのでこういう芸当が出来るんです。
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#4 投稿記事 by イグトランス »

上のは私です。ログインし忘れました。
もう少し書き足したいのに編集できない……。

たとえPrintString(ByVal VarPtr(myString))でできたとしてもそれになんの意味があるかと聞かれれば答えようがありません。
そこへ文字列の代入をしたらまずいですし、文字列内の個々の文字の書き換えは出来ますがこれは別にByValでもできます。
ByRef Longの引数にDWord型の変数を渡したい、というのならまだ使い道がありそうですが。
最後に編集したユーザー イグトランス [ 2005年7月24日(日) 08:48 ], 累計 1 回
Namu
記事: 2
登録日時: 2005年7月23日(土) 10:58

ありがとうございました。

#5 投稿記事 by Namu »

どうもありがとうございました。
解決しました。

ポインタはByRefで宣言するのだと,勝手に間違った解釈をしてしまって
いました。

どうもありがとうございました。
Sinryow
記事: 141
登録日時: 2005年5月31日(火) 09:34
お住まい: 北海道
連絡する:

Re: ありがとうございました。

#6 投稿記事 by Sinryow »

補足しますと。

ByRefは「ポインタを引き渡していないように見せながら実際にはポインタを引き渡す」ものです。
ですので,本当にポインタそのものを引き渡すときはByVal(デフォルト)となります。
' ============================================================
' Sinryow Game Home Page - http://www.sinryow.net/
' Sinryow ActiveBasic Center - http://ab.sinryow.net/
' ============================================================
返信する