よろしくお願いします。
VARIANT型の配列(vaData)を解凍させたいのですが、ソースなど
わかりますでしょうか?
VC6.0でのMFCなのですが!
全くわかりません。
解凍ってことは、何らかの形式で圧縮されているのですか?
圧縮形式がわからないことにはどうにもなりません。
また、何故それがVARIANT型なのかという疑問も…
解凍とは?
VARIANT型配列とは普通に
VARIANT hoge[10];
みたいなものでしょうか?
それとも
VARIANT hoge;
自体が配列なんでしょうか?
VARIANT hoge;
が配列になっている状態です。
今のところSafeArrayCreate();や
Uncompress();を使うのかなと?
>VARIANT hoge;
>が配列になっている状態です。
もうすでに配列になっているのにSafeArrayCreateは使う必要がないでしょう。
これをどうしたいのでしょうか?
「解凍する」の説明がないのでどうしようもできませんけど。
予想)
// BSTR型配列をCStringArrayに変換する
CStringArray ary;
if ( hoge.vt & ( VT_ARRAY | VT_BSTR | VT_BYREF ) ) // VT_BYREFは微妙
{
LONG lb, ub;
SAFEARRAY* psa = *( hoge.pparray ); // psa = hoge.parrayかも。VT_BYREFと関連しそう
::SafeArrayGetLBound( psa, 1, &lb );
::SafeArrayGetUBound( psa, 1, &ub );
::SafeArrayLock( psa );
for ( long i = lb; i <= ub; i++ )
{
BSTR wcs;
::SafeArrayGetElement( psa, &i, ( void* )&wcs );
ary.Add( CString( wcs ) );
}
::SafeArrayUnlock( psa );
}
すみません。
自分でもまだよくわかっていませんので。。。
サンプルコードがあったのですが理解できないです。
// Data (応答データを取得)
long nBufferLen = 0;
PBYTE pBUffer = NULL;
if (m_EditData.GetBufferData(pbyData, &nOffset, &nBufferLen, &pBUffer) == false) {
::GlobalUnlock(hGlobal);
::GlobalFree(hGlobal);
return MAKELRESULT(0, 0);
}
// バイト配列を作成
CComVariant vaData;
SAFEARRAY *psaData = NULL;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = nBufferLen;
psaData = ::SafeArrayCreate(VT_UI1, 1, rgsabound);
// データをコピーする
PVOID pTargetData = NULL;
HRESULT hr = ::SafeArrayAccessData(psaData, (void HUGEP**)&pTargetData);
if (FAILED(hr)) {
::SafeArrayDestroy(psaData);
delete pBUffer; // バッファ開放
::GlobalUnlock(hGlobal);
::GlobalFree(hGlobal);
return MAKELRESULT(0, 0);
}
memcpy(pTargetData, pBUffer, nBufferLen);
::SafeArrayUnaccessData(psaData);
// そのデータをm_vaDataの中に格納する
vaData.vt = VT_ARRAY | VT_UI1;
vaData.parray = psaData;
delete pBUffer; // バッファ開放
とりあえず、サンプルコードはどうでもよくて
結局何をしたいのか説明できますか?
>「解凍する」の説明がないのでどうしようもできませんけど。
の回答がつかないようであれば、私はおります。
圧縮されているデータ(VARIANT配列)を
解凍させたいだけ。
シャノンさんもおっしゃっていますが、
どのように圧縮されていて、どのように解凍するのでしょうか?
(たとえば、ファイルの圧縮方法で、zipの解凍方法とlzhの解凍方法が異なるのと同じで、
どのように圧縮されているのか説明がないとどう解凍してよいのか誰にもわからない)
ktyさん、あなたは他人に
>圧縮されているデータを解凍させたいだけ。
とだけ言われて理解できますか?
すみません。
>どのように圧縮されていて、どのように解凍するのでしょうか?
COMを使って送受信されていますので、
元のデータがどのように圧縮されているかわかりません。
解凍方法はUncompressEx関数を使ってみたんですが、引数の型が合わなく苦戦しています。
> 元のデータがどのように圧縮されているかわかりません。
ならば結論はひとつです。
それがわからない限り、解凍できません。あきらめてください。
> 解凍方法はUncompressEx関数を使ってみたんですが、引数の型が合わなく苦戦しています。
それ、何の関数ですか?
どうも WMI にそんな関数があるみたいですが…
UncompressEx(解凍データ,解凍データ長,圧縮データ,圧縮データ長)
で解凍できると思うのですが、最初のパラメータの解凍データの領域を
作成するにはどうしたらよいのでしょうか?
BYTE型が入ります。
int CCompZLIB::UncompressEx (BYTE *dest, ULONG *destLen,
const BYTE *source,
ULONG sourceLen)
な感じで
CCompZLIB::UncompressExこの関数どっから出てきたんでしょう?
今までの話の流れに全く内容ですけれど、特にCCompZLIB::の部分。
問題のCOMを作った所から提供されていて、それで回答せよという指示が
あるのであれば、それで解凍してくださいとしか言いようが無いですよ。
他から提供されているライブラリを使っているのであれば、
そのライブラリの中身を理解する所からはじめて下さい。
貴方が理解していない物を掲示板を読んでいる人にわかるように
説明できるとはとても思えないです。
少なくともどういうものでどうすれば使えるのか程度は理解していないと
説明できないと思いますよ。
サンプルソースにしても理解していないのなら提示しても意味を成しませんし。
誤字だらけ。
誤)
今までの話の流れに全く内容ですけれど、特にCCompZLIB::の部分。
正)
今までの話の流れに全く無いようですけれど、特にCCompZLIB::の部分。
誤)
問題のCOMを作った所から提供されていて、それで回答せよという指示が
正)
問題のCOMを作った所から提供されていて、それで解凍せよという指示が
あと追記ですが、
サンプルソースと言っても前後の繋がりの部分が欠落しているようなので
その部分が無いと何とも判断できませんし、そもそも何を行う処理のサンプル
なのかも提示されていませんよね。
掲示板は文字でのやり取りになるので少なくとも質問する側が
文字で説明できる程度は理解していないと話が前に進みません。
この辺は御自分で努力していただくしか無いです。
あと、仕事で提供されているものなら提供元にサポートして貰うのが
本当だと思いますが、それは不可能なんでしょうか?
わかりました。
提供元に聞いてみます。
ご迷惑おかけしました。
// 2006/12/01(金) 10:07:52
// のとおり Variant型変数に圧縮されたデータが格納されているという前提
if ( !( vaData.vt & ( VT_ARRAY | VT_UI1 ) ) )
{
// エラー処理
return 0; // 適当
}
SAFEARRAY* psa = vaData.parray;
// 長さの取得
LONG lb, ub;
::SafeArrayGetLBound( psa, 1, &lb );
::SafeArrayGetUBound( psa, 1, &ub );
ULONG nTargetLen = ub - lb + 1;
// データの取得
BYTE* pTargetData = NULL;
HRESULT hr = ::SafeArrayAccessData( psaData, ( void** )&pTargetData );
if ( FAILED(hr) )
{
// エラー処理
return 0; // 適当
}
// 解凍
// ※解凍されるとどれぐらいのサイズになるか不明なので XXXXX とします。
// おそらく「ULONG *destLen」となっていることから、一度CCompZLIB::UncompressEx
// の第一引数にNULLを指定して長さを取得するんだと思うけど。
ULONG destLen = XXXXX;
BYTE* dest = new BYTE[ destLen ];
int ret = CCompZLIB::UncompressEx( dest, destLen, pTargetData, nTargetLen );
// 戻り値によってなんかやる。
// ※戻り値が何なのか不明だからなにもかけん
// destが解凍されたデータ
// 使わなくなったら dest を deleteする
delete dest;
::SafeArrayUnaccessData( psa );
が抜けました。
UncompressExの直後に入れておけばよいかと。
すみません。お願いします。
上記Blueさんのようにコードを書いてみたんですがコンパイルエラーになってしまいました。
error C2664: 'UncompressEx' : 2 番目の引数を 'unsigned long' から 'unsigned long *' に変換できません。 (新しい機能 ; ヘルプを参照)
整数型からポインタ型への変換には reinterpret_cast、C スタイル キャストまたは関数スタイル キャストが必要です。
となります。
宜しければ教えてください。
&がついていなかったです。
>int ret = CCompZLIB::UncompressEx( dest, destLen, pTargetData, nTargetLen );
int ret = CCompZLIB::UncompressEx( dest, &destLen, pTargetData, nTargetLen );
それと、
>// ※解凍されるとどれぐらいのサイズになるか不明なので XXXXX とします。
>// おそらく「ULONG *destLen」となっていることから、一度CCompZLIB::UncompressEx
>// の第一引数にNULLを指定して長さを取得するんだと思うけど。
と書いたように、XXXXXをどのように取得するか明確にしないと、適当適当では
絶対不味いでしょう。
あと
>delete dest;
は
delete[] dest;
でした。
ありがとうございます。
>// ※解凍されるとどれぐらいのサイズになるか不明なので XXXXX とします。
ですが、1M以下になると思われています。
コンパイルしたら
error C2352: 'CCompZLIB::UncompressEx' : 静的でないメンバ関数の中で呼び出しが正しくありません。
'UncompressEx' の宣言を確認してください。
と表示されました。
今試行錯誤していますが。。。
>コンパイルしたら
>error C2352: 'CCompZLIB::UncompressEx' : 静的でないメンバ関数の中で呼び出しが正しくありません。
>'UncompressEx' の宣言を確認してください。
これは、私ではどうにも出来ません。
(というか、CCompZLIB::UncompressExにかんしてなにも情報がないので
この掲示板を見ている人のだれもが解凍できないでしょう)
エラーメッセージの「静的でないメンバ関数」というのから、
インスタンスが必要になるメソッドなんでしょう。
つまり
CCompZLIB::UncompressEx
のような使い方ではなく
CCompZLIB hoge; // コンストラクタが不明なので間違っている可能性がある
・
・
hoge.UncompressEx(、、、、、
てな使い方になるでしょう。
結局のところ
>提供元に聞いてみます。
をやってもらわないとこちらもさっぱりです。
ツイート | ![]() |