人に聞けない痔の悩み、これでスッキリ >>

VB6.0の話です。

 不特定の構造体を文字列(String)に格納し、これを最初の構造体に戻す事はできませんか?

 具体的には「共有メモリを使い構造体を文字列にして格納>別ウインドウで文字列を取得して構造体に戻す」と言う事をやりたいんです。
 共有メモリに不特定の構造体をいれる方法でもいいんですが…VALIANTだとサイズが大きすぎて実用性がありませんし、違う主旨の質問をするのも良くないので回答はあくまで「構造体→文字列→構造体 をする方法」と言う事でお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

APIを使えば出来ます。



Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (cStr1 As Any, cStr2 As Any, ByVal iLen As Long)


構造体→文字列
Call CopyMemory(strB, ByVal typeA, Len(typeA))

文字列→構造体
Call CopyMemory(typeA, ByVal strB, Len(typeA))

ただし構造体のメンバに配列があると使えません(VBの配列はメモリを連続してとらない為、メモリーリークします)。

また構造体の中身は string *5 などの固定長である必要があります。

以上です。

この回答への補足

 …やってみたのですが、デバックするとCopyMemoryの時にVBごと落ちてしまいます。構造体のサイズの問題なんでしょうか?

補足日時:2004/11/17 10:15
    • good
    • 0
この回答へのお礼

 CopyMemoryですか。ありがとうございます。まさにこれがほしかったんです。

お礼日時:2004/11/16 19:47

こんな感じです。



Private Type typBuff
  sBuff As String * 6  '12Byte
End Type
Private mBuff  As typBuff

Private Type typData
  a As Long '4Byte
  b As Long
  c As Long
End Type



Private Sub Command1_Click()
  Dim Dat As typData
  With Dat
    .a = 2
    .b = 4
    .c = 6
  End With
  
  LSet mBuff = Dat
  
End Sub

Private Sub Command2_Click()
  Dim Dat As typData
  LSet Dat = mBuff
  MsgBox Dat.a & "," & Dat.b & "," & Dat.c
End Sub
Sub
    • good
    • 2
この回答へのお礼

 原理としてはCopyMemoryと同じですよね?なんとなくこっちの方がすっきりしている気はしますけど。
 実は、扱う構造体の中はLong型とString型なので、Longが使えるかどうか多少不安だったんですが、これで大丈夫と分かりました。
 ありがとうございました。

お礼日時:2004/11/17 09:08

#2です。



#3の方が「化けるのでは」? と言われていますので、いちおう補足しておきますね。

これによって化ける事はありません。その為に値渡ししていますので(値渡しする事によって、暗黙の変換を回避しています)。

実際に開発したシステムで、長らく使っていますので問題はないはずです。

ただメモリ操作をするのであれば、バイナリで扱った方が無難なのは確かです。
    • good
    • 0
この回答へのお礼

 やはりバイナリになりますか。ポインタの事は分かっているのでCでなら作れるのですが、VBのポインタがどういう物になるのかが良くわからなくて…まあ、いい訳じみてますが。
 やはり、暇を見てバイナリの事は勉強しておきたいです。

お礼日時:2004/11/17 09:03

回答2と同じく RtlMoveMemory を使うけど、文字列で渡すと


暗黙にUnicode/SJIS変換がされるので、化けるでのでは?
やはり、バイナリで渡すべきと思います。

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=250487

この回答への補足

 ちなみに、仕様の関係で直接RtlMoveMemoryを使って構造体をファイルマップ上に移すことは出来ないんです。
 なので、バイナリなり文字列なりに一度格納する必要が出るのですが…格納できても取り出せないという訳なんです。

補足日時:2004/11/17 10:11
    • good
    • 0
この回答へのお礼

 参照まで用意していただいて本当にありがとうございます。
 実は、最初の方のレスが来た時にこのスレットは見つけていたんですが…構造体→バイナリ→共有→バイナリ…までは行くんですが、バイナリ→構造体がどうしても出来なくて…

お礼日時:2004/11/17 09:01

何でバイナリ(byte配列)ではなく文字列?


「構造体→バイナリ→共有メモリ→バイナリ→構造体をする方法」過去ログにあるはずです
    • good
    • 0
この回答へのお礼

 バイナリは正直良く分からないので使いたくなかったのですが…そうした方が効率はいいですよね、やっぱり。
 一応過去ログ漁ってみたのですが…具体的にどこの過去ログの事でしょうか?

お礼日時:2004/11/16 19:45

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QVBの「As String * 128」とは?

VBの「As String * 128」とは?

Visual Basic 2010 Expressでコンソールアプリケーションを作成しています。

OSのヴァージョンを取得する機能を作成したかったので、

http://hanatyan.sakura.ne.jp/vbhlp/Version.htm

を参考にして、OSVERSIONINFOの構造体を定義しました。

しかし
szCSDVersion As String * 128

「* 128」
の部分で、ステートメントの終わりを指定してくださいとエラーが出ます。

「* 128」とは、いったいどういう意味ですか?

また、エラーを無くす方法はありますか?

いろいろ検索しましたが、調べ方が悪いのか、分かりませんでした。

よろしくお願いします。

Aベストアンサー

参考にされたサイトはVB6.0用のソースですね。
VB6.0とVB2010(=VB.NET)は色々な部分が変わってますので、VB.NET用のサンプルを見た方が良いと思います。

http://dobon.net/vb/dotnet/system/osversion.html

ちなみに一応、質問に答えると…

> 「* 128」とは、いったいどういう意味ですか?

VB6.0(VB2010の5世代前のバージョン?)で固定長文字列を表す定義です。
* 128と記述すると128文字以上の文字列を入れても自動的に128文字でカットされます。

> また、エラーを無くす方法はありますか?

VB2010(=VB.NET)では以下のように記述します。
<VBFixedStringAttribute(128)> Private szCSDVersion As String

QVB6.0の「vbFromUnicode」はVB.NETではどれに相当しますか?

VB6.0で、例:StrConv(Text, vbFromUnicode)とかで使用する、
「vbFromUnicode」(文字列を Unicode からシステムの既定のコードページに変換する)
は、VB.NETでは使用できないようです。(相当する定数はない?)

「vbFromUnicode」と同等の機能を、VB.NETで使用したいのですが、
どうすれば良いでしょうか?

Aベストアンサー

思いっきり、例文に「COM1」と書いてますが、USBに書き換えてくださいね^^;

それとふと思ったのですが
udtReaderWriterModeWithoutEncryption
変数は構造体ですよね?

メンバが
lngPortName
lngBardRate
というのは、型宣言をINTEGERに変換してますよね?

ちょっとばかり不安に思ったので、追記しておきました。

参考URL:http://okweb.jp/kotaeru.php3?q=1257613

QVBで構造体の配列を関数に渡す方法?

構造体の配列のアドレスを関数に渡して使用したいのですが、どのようにしたら良いでしょうか?教えて下さい。

Aベストアンサー

例えば、こんな感じ
Type POINT
x As Integer
y As Integer
End Type

Sub testMain()
Dim a(3) As POINT
Dim i

a(0).x = 1: a(0).y = 10
a(1).x = 2: a(1).y = 20
a(2).x = 3: a(2).y = 30
a(3).x = 4: a(3).y = 40
Call times2(a) '2倍する
For i = 0 To UBound(a)
Debug.Print a(i).x; ","; a(i).y
Next

End Sub
Sub times2(ByRef a() As POINT)
Dim i
For i = 0 To UBound(a)
a(i).x = a(i).x * 2: a(i).y = a(i).y * 2
Next
End Sub

QVBAの構造体について

大変、初歩的なことで、恐縮なんですが、教えて下さい。

やりたいことは、
文字列(50バイト)を1バイトずつ切り分けたいんです。
MIDを使う方法じゃなくて、
配列で再定義をするような方法を教えてください。

Aベストアンサー

あ、なるほど。そういう手もありましたね。>#2,TAGOSAKU7 さん

APIを使わないのであれば、

Type typS1
  a As String * 1
  b As String * 1
  c As String * 1
  d As String * 1
  e As String * 1
  f As String * 1
End Type

Type TypS2
  a As String * 6
End Type

Type TypS3
  a(5) As String * 1
End Type

Sub test()
  Dim S1 As typS1
  Dim S2 As TypS2
  Dim S3 As TypS3
  
  S2.a = "一二三四五六"
  LSet S1 = S2
  MsgBox S1.c
  
  LSet S3 = S2
  MsgBox S3.a(2)
End Sub


ってな方法も…

Qbyte型をstring型として扱うには

今日の質問/マイページに反映されないので、再度の質問です。
windows2000-sp4/vb6-sp5環境です。ユニコードのデータをvbで直接入出力し、vb内でstring型で扱いたいとおもっています。今のところ、vbの入出力では、自動的にsjis/unicode変換がされるので、binaryで受け取り、string型にするのかなと思っています。byte型で受け取り、APIの"MoveMemory"("RtlMoveMemory")でstring型にcopyするのかなとは思っているのですが、うまくいきません。経験不足そのものです。vbでのbyte型とstring型双方向のbinaryな変換の方法をお教えください。

Aベストアンサー

dim s as string
dim b() as byte

'文字列 -> byte配列
b = s

'byte配列 -> 文字列
s = b

Qファイルマッピングについて

ファイルマッピングについての質問です。
現在CreatFileMapping、OpenFileMapping、MapViewOfFileをつかって
EXE間のデータのやり取りをしているのですが、
このファイルマッピングを利用して構造体を
やりとりする事は出来ないものでしょうか?
開発環境はWinNT4とVB6です。よろしくお願いします。

Aベストアンサー

試してみました。

gOpenFileMappingMapViewOfFileFileMapReadFileMapWrite.vbpの変更点
---
Private Declare Sub MoveMemory Lib "kernel32.dll" _
Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)

Private Type tyData
x As Long
y As Long
b(9999) As Byte
s As String * 1024
End Type
Private Data As tyData

Command1_Click()
Data.s = Text1.Text
' 文字列をコピー
Call MoveMemory(ByVal lngFileMapViewAddress, Data, Len(Data))

Command2_Click()
Data.s = ""
Call MoveMemory(Data, ByVal lngFileMapViewAddress, Len(Data))
Label3.Caption = RTrim(Data.s)

Command3_Click()
lngFileMapSizeLow = Len(Data)
---
普段はEXE間のデータはファイルで渡していますが、ファイルマッピングも
結構いいですね。今後、挑戦したいです。

試してみました。

gOpenFileMappingMapViewOfFileFileMapReadFileMapWrite.vbpの変更点
---
Private Declare Sub MoveMemory Lib "kernel32.dll" _
Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)

Private Type tyData
x As Long
y As Long
b(9999) As Byte
s As String * 1024
End Type
Private Data As tyData

Command1_Click()
Data.s = Text1.Text
' 文字列を...続きを読む

Qバイト型のデータをLong型に変換

初歩的なことですみません。

Dim a(0 to 3) as Byte
Dim b as Long
と宣言します。
この変数aをLong型のbに変換するにはどのように
したらよいのでしょうか?
逆にbの値をaに変換する方法もできましたらお願いします。

Aベストアンサー

色々な方法があります。

(1)論理演算子

a(0) = b And &HFF#
a(1) = (b And &HFF00#) / &H100#
a(2) = (b And &HFF0000#) / &H10000#
a(3) = (b And &H7F000000#) / &H1000000#
If (b And &H8000000) Then
a(3) = (a(3) Or &H80)
End If

(2)ファイル

Open "temp.tmp" For Binary As #1
Put #1, 1, b
Get #1, 1, a
Close #1

(3)RtlMoveMemory

Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal length As Long)
MoveMemory a(0), b, 4
MoveMemory b, a(0), 4

--
(2)が手堅く応用が利くかと。
(3)はlongならいいが、4の倍数でない型は問題あるかも。

色々な方法があります。

(1)論理演算子

a(0) = b And &HFF#
a(1) = (b And &HFF00#) / &H100#
a(2) = (b And &HFF0000#) / &H10000#
a(3) = (b And &H7F000000#) / &H1000000#
If (b And &H8000000) Then
a(3) = (a(3) Or &H80)
End If

(2)ファイル

Open "temp.tmp" For Binary As #1
Put #1, 1, b
Get #1, 1, a
Close #1

(3)RtlMoveMemory

Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (D...続きを読む

Qアドレスでの参照の仕方

VB初心者です。
Cは、ポインタ変数にアドレスを入れると、
実態を参照してくれますが、
それをVBでは、どうすればいいのでしょうか??
VBでC関数から文字列が格納されているアドレスを受け取って、
実態の文字列を参照したいのですがどうやったら参照できるのでしょうか??
よろしくお願いします。

Aベストアンサー

文字列のアドレスを渡して、そのアドレスに文字列
が返却されるタイプであれば、単純に文字列を指定
すればOKです。

関数側で、メモリを確保して、そのアドレスが
返ってくるタイプのインタフェースの場合、VBで
は、ポインタを処理する型がないため、そのアドレ
スの内容を自分の変数の領域に移動させることで、
読み取ります。

移動させる関数は、RtlMoveMemoryで、下記では、
MemCopyとして定義しています。これを使って、
Dimで定義した文字列の領域に(移動前に、必要な
だけの文字を入れておくこと)コピーすればOK
です。

Public Declare Sub MemCopy _
Lib "Kernel32" Alias "RtlMoveMemory" _
(hpvDest As Any, _
hpvSource As Any, _
ByVal cbCopy As Long)

文字列のアドレスを渡して、そのアドレスに文字列
が返却されるタイプであれば、単純に文字列を指定
すればOKです。

関数側で、メモリを確保して、そのアドレスが
返ってくるタイプのインタフェースの場合、VBで
は、ポインタを処理する型がないため、そのアドレ
スの内容を自分の変数の領域に移動させることで、
読み取ります。

移動させる関数は、RtlMoveMemoryで、下記では、
MemCopyとして定義しています。これを使って、
Dimで定義した文字列の領域に(移動前に、必要な
だけの文字を入れ...続きを読む

QVB6.0-整数と余りを求める

表題の通り、整数と余りを求める関数を教えてほしいです:例:100/60=1余り40
整数:1
余り:40
よろしくお願いいたします。

Aベストアンサー

Dim A,B,C,D as integer
A=100
B=60
C=Int(A/B) <---答は1
D=A mod B

●IntはAをBで割った時の整数部分を求める関数ですが、答が負の場合は
注意が必要です。 例 Int(-100/40)=-2
これを回避する場合 Fixがいいです

●mod は A を B で割った時の余りを求める関数

Qこの型変換の内容がわかりません(LSet)

こんにちわ。以下のプログラムを解読しているのですが、型変換がどう行われているのかがわからなくて困っています。
『←ココ!!』となっているところの型変換です。PのLong型をByte型へ変換しているとは思うのですが、内容をみるとどうなってそうなったのかわからないのです。『←ココ!!』の後の値を見てみると、
bP.bP(3)は「0」
bP.bP(2)は「188」
bP.bP(1)は「97」
bP.bP(0)は「78」
となっています。LSetで「P:12345678」がどうなってこうなったのでしょうか?

教えていただけるとうれしいです。宜しくお願いしまっす。

***プログラム***
’宣言
Const P As Long =12345678
Private Type bytP
bP(3) As Byte
End Type
Private Type lngP
lP As Long
End Type
Dim bytB(4) As Byte

’mainの中
lP.lP = P
LSet bP = lP 『←ココ!!』
bytB(0) = bP.bP(3)
bytB(1) = bP.bP(2)
bytB(2) = bP.bP(1)
bytB(3) = bP.bP(0)
******************

こんにちわ。以下のプログラムを解読しているのですが、型変換がどう行われているのかがわからなくて困っています。
『←ココ!!』となっているところの型変換です。PのLong型をByte型へ変換しているとは思うのですが、内容をみるとどうなってそうなったのかわからないのです。『←ココ!!』の後の値を見てみると、
bP.bP(3)は「0」
bP.bP(2)は「188」
bP.bP(1)は「97」
bP.bP(0)は「78」
となっています。LSetで「P:12345678」がどうなってこうなったのでしょうか?

教えていただけるとうれしいです。...続きを読む

Aベストアンサー

LSet は、既に説明があるとおり、
ユーザー定義型のメモリ領域のコピー
なんで
12345678 を16進表現にすると、00BC614Eですから
00=0
BC=188
61=97
4E=78
ですね。
やってることは、LongをByteに切り分けているということだと思います。
単に代入するだけでいいので楽ということでしょうね。
ちょうど、C言語で言うunion みたいな感じの使い方ですね。


人気Q&Aランキング

おすすめ情報