いつもお世話になってます。
下記のページを参考にして変数のコピーをRtlMoveMemoryを使って行う方法を勉強中ですが、変なエラーがでてうまく行きません。
http://msdn.microsoft.com/en-us/library/aa366788(VS.85).aspx
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
Private Sub test()
Dim a As String, b As String
a = "あああaaa"
Debug.Print LenB(a)
MoveMemory VarPtr(b), VarPtr(a), LenB(a)
MsgBox b
End Sub
LenB(a)をLen(a)に変えたらうまくいくようなのですが、第3引数にはコピーするバイト数を指定するのではないのでしょうか?ご教示ください。
>LenB(a)をLen(a)に変えたらうまくいくようなのですが、
a = "あああaaa" では、Len(a)= 6 になり、異常終了しませんか?
>第3引数にはコピーするバイト数を指定するのではないのでしょうか?
多分、この場合は、文字列のポインタをコピーしているので、Long 型の
4 バイト固定でいいのではないでしょうか?
Private Sub test()
Dim a As String, b As String
a = "あああaaa"
MoveMemory VarPtr(b), VarPtr(a), 4
MsgBox b
a = "a"
MoveMemory VarPtr(b), VarPtr(a), 4
MsgBox b
a = "あああaaaあああaaa"
MoveMemory VarPtr(b), VarPtr(a), 4
MsgBox b
End Sub
花ちゃん様、ありがとうございます。
うまくいきました。
僕の最初の書き方のようにしようとすると一度byte型で受ける必要があると考えましたがあってますでしょうか?
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Sub test3()
Dim a As String, b As String
Dim c() As Byte, d() As Byte
a = "あああaaa"
ReDim c(0 To LenB(a) - 1)
ReDim d(0 To LenB(a) - 1)
c() = a
MoveMemory d(0), c(0), UBound(c) + 1
MsgBox d
End Sub
最初と、その後のAPI宣言で変数の渡す方法が違うのは
意図的なものですか?
Abyss様、いつもご指導ありがとうございます。
配列を引き渡すので参照引渡ししないとだめなのかと思いました。間違っていますでしょうかl?
いいえ。間違いとかではありません。
参照渡し、値渡しの問題がなければ良いとします。
気になっただけですので。
Abyss様、いつもありがとうございます。
APIは勉強を始めて日が浅く、まだまだ見習い状態です。今後ともなにかありましたらご指摘くださると非常にうれしいです。
今回のご質問はAPIよりVB6における
文字列(String型)の扱いが問題な気がします。
dim c() as byte
c = "あああaaa"
の場合、cは文字列(String型)ではありませんよね?
msgbox c
とした場合、VBが文字列への変換をしてくれただけです。
Abyss様
いつもお世話になっております。
>cは文字列(String型)ではありませんよね?
>msgbox c
>とした場合、VBが文字列への変換をしてくれただけです。
ここは意図してやっていました。花ちゃん様とAbyss様のご指導により、僕が当初理解できていなかったのは、文字列型の変数が参照型ということがわかっていなかったのだと気づきました。
string型変数を書き換えるときは参照型変数の確保領域の4バイトを引き渡して、Byte型を引き渡すときは、Byte数を引き渡す必要があると理解しましたが、あってますでしょうか?
> ここは意図してやっていました。
了解です。
> ...あってますでしょうか?
と思います。文字列をバイト単位で扱う一つの例です。
Declare Sub MoveMemory Lib "Kernel32" Alias "RtlMoveMemory" _
(pDest As Any, pSrc As Any, ByVal cbLen As Long)
Sub Test()
Dim a As String, c() As Byte
a = "あああaaaあああaaaa"
ReDim c(1 To LenB(a))
MoveMemory c(1), ByVal StrPtr(a), LenB(a)
MsgBox c
End Sub
学習のためですと↓のもご参考になるかと。
余計でしたらすみません。
Dim a As String, c() As Byte
Dim i As Long
a = "あああaaaあああaaaa"
'LenB(a)の代わり...
MoveMemory i, ByVal StrPtr(a) - 4, 4
MsgBox "文字列のバイト長=" & i
ReDim c(1 To i)
MoveMemory c(1), ByVal StrPtr(a), i
MsgBox c
Abyss様ありがとうございます。
>MoveMemory c(1), ByVal StrPtr(a), LenB(a)
なるほど。勉強になります。今回の質問をさせていただくまで、StrPtr、VarPtrの違いがよく分かってなかったことにも気づきました。
>MoveMemory i, ByVal StrPtr(a) - 4, 4
bstr型についても、このように調べると書物で読むより、理解が深まります。本当にありがとうございました。とてもすっきりしました。