プログラミング

SFC mini ver 1.0.5 β

2008年4月24日

Windows Vista対応の、SFC mini バージョン 1.0.5 ベータをリリースしました。利用の際は、1.0.1に上書きした後にinstall.vbsを実行してください。

とりあえず、ベータバージョンとします。もし不具合がある場合は、お知らせいただければうれしいです。

次の正式バージョンは 1.1.0 の予定で、現在の 1.0.5 のメモリ管理を少し見直し、ヘルプファイルを少し書き直してリリースの予定です。同時に、SFC mini のためのフォーラムを暫定的に立ち上げるかもしれません。

SFC mini ver 1.0.5 βは、SourceForge.jp からダウンロード可能です。

コメント

クリオネ (2009年8月18日 08:12:23)

はじめまして

DymamicWrapper に限界を感じて SFC Mini への乗換えを検討しているプログラマです。
非常に使いやすく素晴らしいコンポーネントですね。
色々と試していて、ひとつだけうまく置き換えの利かない部分がありました。

SfcMini.Structure で任意のサイズの Byte 型を指定できるようになりませんか。
"String" や "Unicode" の文字列バッファではなく
単にバイナリデータを受け取るバッファが欲しいのです。
通常の VBScript や JScript では扱えない型になりますが、
XMLHttpRequest の responseBody で受け取れる型と同一であれば
ADODB.Streamに流し込んで扱えるようになります。
VarType だと 8209 (vbByte(17) + vbArray(8192)) です。
例えば Win32API の ReadFile などでバイナリデータを読み出すときに必要です。

SfcMini.Structure では

var data = new ActiveXObject('SfcMini.Structure');
data('value', 'Byte*1000');

のような感じで指定できるとうれしいです。
現状では以下のように Byte型の配列を定義すると
Long 型の VARIANT配列になってしまうようで
期待した動作とは異なりました。

data('value(1000)', 'Byte');

1.0.1では

data('value', 'Unicode*500');

のように無理やり BinaryString にコピーさせて切り抜けていましたが
1.0.5b では 終端文字列までしか認識されず
0x00 を含むバイナリデータとして扱えなくなってしまいました。

以上ご一考いただけたら幸いです。

Kat (2009年8月19日 18:49:00)

"String*1000"でうまく行きませんか?

クリオネ (2009年8月21日 15:51:45)

返信ありがとうございます。
その後、同梱のソースを読ませていただきました。
文字列処理に関して気になる部分が何箇所かあったので弄ってみたところ、
NULL を含んだ文字列でも期待通りの動作をするようになりました。
一部 SysAllocString を SysAllocStringLen に置き換えています。
差し出がましいとは思いましたが、変更箇所を載せておきます。
拙いコードですが少しでもお役に立てれば幸いです。
(当方 XP 環境であり、Vista では未確認です)

[common.cpp]

追加)
BSTR ConvertANSItoBSTR(LPSTR mbs, int mbs_len)
{
int wcs_len = MultiByteToWideChar(CP_ACP, 0, mbs, mbs_len, NULL, 0);
wchar_t *wcs = new wchar_t[wcs_len];
MultiByteToWideChar(CP_ACP, 0, mbs, mbs_len, wcs, wcs_len);
BSTR bstr;
bstr = SysAllocStringLen(wcs, wcs_len);
delete wcs;
return bstr;
}

変更)
LPWSTR CreateUnicode(LPWSTR Unicode, COMDATA* data, int temporary)
{
if (!Unicode) return 0;
//Copy Unicode
int BuffLen=wcslen(Unicode)+1;
LPWSTR Unicode2=(LPWSTR)((int)data->Malloc(BuffLen*2,temporary));
wcscpy_s(Unicode2,BuffLen,Unicode);
return Unicode2;
}

変更)
char* CreateAnsiString(LPSTR ANSI, COMDATA* data, int temporary)
{
if (!ANSI) return 0;
//Copy ANSI
int StrLen=strlen(ANSI)+1;
char* str=(char*)data->Malloc(StrLen,temporary);
strcpy_s(str,StrLen,ANSI);
return str;
}

削除)
LPWSTR CreateFixedLengthUnicode(LPSTR ANSI,COMDATA* data, int length, int temporary)
LPWSTR CreateFixedLengthUnicode(LPWSTR Unicode,COMDATA* data, int length, int temporary)
LPWSTR CreateUnicode(LPSTR ANSI,COMDATA* data, int temporary)

[structure.cpp]

L162
前) pVarResult->bstrVal=SysAllocString(CreateUnicode((LPSTR)*pInt,data,MALLOC_TEMPORARY));//copy as Unicode for export
後) pVarResult->bstrVal=MultiByteToBSTR(ANSI,-1);//copy as Unicode for export
L168
前) pVarResult->bstrVal=SysAllocString(CreateUnicode((LPWSTR)*pInt,data,MALLOC_TEMPORARY));//copy Unicode for export
後) pVarResult->bstrVal=SysAllocString((LPWSTR)*pInt);//copy Unicode for export
L176
前) pVarResult->bstrVal=SysAllocString(CreateFixedLengthUnicode(ANSI,data,i,MALLOC_TEMPORARY));
後) pVarResult->bstrVal=MultiByteToBSTR(ANSI,i);
L182
前) pVarResult->bstrVal=SysAllocString(CreateFixedLengthUnicode(Unicode,data,i,MALLOC_TEMPORARY));
後) pVarResult->bstrVal=SysAllocStringLen(Unicode,i);
[tools.cpp]

L82
前) pVarResult->bstrVal=SysAllocString(CreateUnicode(ANSI2,data,MALLOC_TEMPORARY));
後) pVarResult->bstrVal=ConvertANSItoBSTR(ANSI2,-1);
NULL 文字を含む文字列の動作確認は以下のスクリプトで行いました。

var API = new ActiveXObject('SfcMini.DynaCall');
API.LoadLibrariesW('kernel32', 'user32');
var buf = new ActiveXObject('SfcMini.Structure');
buf('value', 'Unicode*1000');
var len = API.GetPrivateProfileSection('boot loader', buf, 1000, 'C:\\boot.ini');
API.MessageBox(0, buf.value.substr(0, len).replace(/\u0000/g, '\n'), 'test', 0);

Kat (2009年8月24日 10:31:26)

なるほど、そこの部分ですか。どうも有り難うございます。

少しの間、SFC mini のコードは眺めていなかったのですが、時間が取れれば見てみます。

コメント送信