【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?

OS: WinXP sp2
開発: VB6 sp5 <--> VC6 sp5 MFC OCX

いままでVB/VC間のデータのやりとりをStringで行っていたアプリがありまして、現在はVB側から見たインターフェースをByte()へ変更する作業を行っています。

まず VB --> VC に関して質問ですが

Dim byteStream(5) As Byte
byteStream(0) = 1
byteStream(1) = 2
byteStream(2) = 3
byteStream(3) = 4
byteStream(4) = 5

などとし、メソッドに対してbyteStreamをVariantで渡してやって
C側から const VARIANT FAR& で参照してきて、
この.pcVal(配列の先頭アドレスが入っているはず)をchar*で受け取ろうと思いました。
するとこのアドレスには、先頭のbyteStream(0)の値しか入ってきません。
VB側でVariant = Byte()とするときに値渡しになっているっぽい?のですが、仕組みがわかりません。
この理由が知りたいです。
ODLファイルを変更して対処すべきかもしれませんが、MFCのウィザードが「慎重に行ってください。」とコメントしているので質問させていただきました。

VB側でのメソッドの宣言:
Function SendVariantStream(stream, length As Integer) As Boolean

odlファイルでの宣言:
boolean SendVariantStream(VARIANT stream, short length)

VCの宣言:
BOOL SendVariantStream(const VARIANT FAR& stream, short length);

A 回答 (1件)

VC側で受け取ったときですが、配列を渡しているので、SafeArrayAccessDataを使ってアクセスするべきだと思います。


参照渡しか、値渡しかで、parrayを使うか、pparrayを使うか変わります。
どちらでもいけるようにすると、こんな感じかな...余分なチェックも入ってる気がするけど (^-^;

VARIANT *va;
SAFEARRAY*psa;
HRESULThr;
VARIANT*pi;

if (stream.vt == (VT_VARIANT|VT_BYREF)){
va = stream.pvarVal;
} else {
va = &stream;
}
if ((va->vt & VT_ARRAY) != VT_ARRAY){
ThrowError(CTL_E_INVALIDPROPERTYVALUE, "引数が配列ではないぞ", 0);
}

if (va->vt & VT_BYREF){
psa = *va->pparray;
} else {
psa = va->parray;
}

hr = SafeArrayAccessData(psa, (void **)&pi);
for(int i=0 ; i<arraylen ; i++){
int type = pi[i].vt;
int val = pi[i].cVal // ← 1バイト整数の場合、cValにデータが入る
}
SafeArrayUnaccessData(psa);

参考URL:http://program.station.ez-net.jp/special/vc/atl- …
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。渡せました!
COMの配列がこんなことになってるということ自体を知りませんでした。排他ロックがかかるんですね。
URLを参考に、VC->VBも書いてみました。

//
// VC ---> VBのコード
// buf: C側のバッファ
// bufsize : 渡したい配列の大きさ
//

SAFEARRAYBOUNDbound[1];
rgb[0].cElements = bufsize;
rgb[1].lLbound = 0;

_variant_t variantStream;
variantStream.vt = (VT_ARRAY | VT_UI1); 内部形式をバイト配列とする
variantStream.parray = ::SafeArrayCreate(VT_UI1, 1, bound); // Byte配列を作成

char* tmpbuf;   // SafeArrayにアクセスするため一時的に使用するポインタ
::SafeArrayAccessData(variantStream.parray, (void**)&tmpbuf); // アクセス開始
::RtlCopyMemory(tmpbuf, buf, bufsize); // バッファをSafeArrayにコピー
::SafeArrayUnaccessData(variantStream.parray); // SafeArrayを再びロック

---> variantStreamをVBへ

#
# まだ、SAFEARRAYBOUNDの意味が微妙によくわかってませんが、
# 一応渡すことができました。ありがとうございます
#

お礼日時:2006/06/08 20:29

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


おすすめ情報