曲名 | スコア | 記録 | 曲名 | スコア | 記録 | |||||
---|---|---|---|---|---|---|---|---|---|---|
天使の歌う小夜曲 | 66174 | (95.82%) | 普通 | 69063 | 羽根のブランケットにつつまれて | 62573 | (98.11%) | 普通 | 63776 | |
永久に続く物語 | 42579 | (91.23%) | 普通 | 46671 | Aozora Melody | 148180 | (97.62%) | 普通 | 151789 | |
らぶりーすまいる(ショートver) | 91889 | (96.22%) | 普通 | 95498 | らぶりーすまいる | 189355 | (96.33%) | 普通 | 195577 | |
Ancient View | 62436 | (89.20%) | 普通 | 68793 |
常識かも知れないけど自分用のメモ。
WinRT APIのrefクラスはポインタ*の代わりに^を、参照&の代わりに%を用いる。メモリ管理はOSがやってくれているはずなので意識しなくていい。
例えばPlatform::String^ str として関数f()内部でstr自体を書き換えるときは, やはりポインタのポインタを渡さなければならないので宣言はf(Platform::String^* str)としなければならず, 呼び出しはf(&str)とする必要がある。
文字列関係
Platform::String^ string; // WinRT文字列クラス
wchar_t *str; // 2バイト文字へのポインタ
std::wstring wstr; // C++ライブラリの2バイト文字クラス
・string → str
str=new wchar_t[string->Length()+1];
wcscpy_s(str,string->Length()+1,string->Data());
(使い終わったら delete [] str;)
・str → string
string=ref new Platform::String(str);
・str → wstr
wstr=string->Data();
・wstr → string
string=ref new Platform::String(wstr);
・wstr → str(これはWinRT関係ないけど)
str=new wchar_t[wstr.length()+1];
wcscpy_s(str,wstr.length()+1,wstr->c_str());
(使い終わったらdelete [] str;)
・str → wstr
wstr=str;
std::wstringはPlatform::Stringよりはだいぶましだけど, printf的なものを使いたいときは結局wchar_t配列にしてsnwprintf_sとか使うしかない??
で、バイナリ列とか1バイト文字コード系とかを扱う標準的な方法が無く、何故かWindows::Security::Cryptography以下に使えるクラスがあるのでそれを使う。基本はArray^。あと所々Windows::Storage::Streams::IBuffer^ が使われることが多いけどこいつが非常に使いづらいのでデータの取りだし方なども。Arrayは基本的に長さ情報付きのバイト列。長さの変更は出来ない(短くするのも不可)。realloc的なことも出来ないので別に作ってコピーするしかない。
Array^ arr;
に対してarr->Dataで実体のバイト列先頭へのポインタ, arr->Lengthで長さが取得出来、長さの範囲内で普通のポインタとして自由に読み書き出来る。
既にバイト列BYTE *data があってメモリもsizeバイト分確保されているときは、
ArrayReference(data,size)
であたかもArray型のように使用することが出来る(普通のArrayを作ってコピーするより効率がよい)。ただrefクラスになる訳ではないので、メモリ管理などは自分でやらなければならないし、別のスレッドや非同期操作に渡すのは使用時には実体が削除されてしまっていることもあるため非常に危険。
・IBuffer^ bufからデータを取り出す
Array^ arr;
Windows::Serurity::Cryptography::CryptographicBuffer::CopyToByteArray(buf,&arr);
でarrのインスタンスが作成されてデータが入って帰ってくる。CryptographicBufferはstaticなメソッドを集めたクラスなのでインスタンス化は必要ないというか出来ない。
arrは新規作成されるので、既にあるバイト列にArrayReferenceなどを使ってデータを移すことは出来ない。一度上の方法でarrを作ってからコピーするしかない。
・IBufferにデータを入れる
Windows::Storage::Streams::IBuffer^ buf=Windows::Serurity::Cryptography::CryptographicBuffer::CreateFromByteArray(arr);
こちらは読み出すだけなのでバイト列を使うときはArrayReferenceを用いればOK。
1バイト文字列は最後が\0のバイト列扱いで直接扱う関数は殆ど無い。Platform::String^(要するにUTF16) <--> UTF8 の変換だけはメソッドが用意されている。ちなみにただのASCIIというのも無いのでUTF8を代わりに用いる。
・Platform::String^ str → UTF8
IBuffer^ buf=Windows::Security::Cryptography::CryptographicBuffer::ConvertStringToBinary(str,Windows::Security::Cryptography::BinaryStringEncoding::Utf8);
最後のUtf8のところをUtf16LE, Utf16BEにするとリトルエンディアン、ビッグエンディアンのUTF16に変換する事も一応可能。
戻り値はIBufferなので、自分で使うには上記の方法でバイト列を取り出さないといけない。NULL終端されているかは未確認なので注意。
・IBuffer^ buf (中身はUTF8文字列) → Platform::String^
Platform::String^ str=Windows::Security::Cryptography::CryptographicBuffer::ConvertBinaryToString(Windows::Security::Cryptography::BinaryStringEncoding::Utf8,buf);
これも事前にIBufferに目的の文字列を入れておく必要がある。
UTF8以外のSJISとかEUCへの変換はクラス見つからなかったので仕方ないので従来通りのmbstowcs_s, wcstombs_sを用いる。例えばSJISにするならまず
size_t length=0;
_locale_t locale=_create_locale(LC_ALL,"japanese_jpn.932");
_wcstombs_s_l(&length,NULL,0,str->Data(),_TRUNCATE,locale);
とするとlengthに終端含めた必要サイズが入って戻ってくるので、
char *result=new char[length];
_wcstombs_s_l(&length,result,length,str->Data(),_TRUNCATE,locale);
として実際に変換する。ちなみにEUC-JPのロケールはjapanese_jpn.20932。
resultをchar *として確保せずにArray^ result=Array(length); として_wcstombs_s_lの引数として(char*)result->Data()を使ってもOK。
逆は
size_t length=0;
_locale_t locale=_create_locale(LC_ALL,"japanese_jpn.932");
_mbstowcs_s_l(&length,NULL,0,(char*)src->Data,src->Length,locale);
wchar_t *buf=new wchar_t[length];
_mbstowcs_s_l(&length,buf,length,(char*)src->Data,src->Length,locale);
で、必要に応じてPlatform::String^ str=ref new Platform::String(buf); してPlatform::String^に変換しておく(この場合はその後すぐにbufはdeleteしてOK)。
SJIS,EUC以外にも変換出来るはずだけど、ロケール名をどうすればいいのかどこを調べても書いてないのでとりあえずHTTPにアクセスした戻り値のcharsetを見て動作を返るなどは難しそう。
フォルテールは小夜曲初回65151, コースは永久→AV→らぶすまショートで初回は36978,62436,87474。らぶすまロングは182651から。
WinRT APIのrefクラスはポインタ*の代わりに^を、参照&の代わりに%を用いる。メモリ管理はOSがやってくれているはずなので意識しなくていい。
例えばPlatform::String^ str として関数f()内部でstr自体を書き換えるときは, やはりポインタのポインタを渡さなければならないので宣言はf(Platform::String^* str)としなければならず, 呼び出しはf(&str)とする必要がある。
文字列関係
Platform::String^ string; // WinRT文字列クラス
wchar_t *str; // 2バイト文字へのポインタ
std::wstring wstr; // C++ライブラリの2バイト文字クラス
・string → str
str=new wchar_t[string->Length()+1];
wcscpy_s(str,string->Length()+1,string->Data());
(使い終わったら delete [] str;)
・str → string
string=ref new Platform::String(str);
・str → wstr
wstr=string->Data();
・wstr → string
string=ref new Platform::String(wstr);
・wstr → str(これはWinRT関係ないけど)
str=new wchar_t[wstr.length()+1];
wcscpy_s(str,wstr.length()+1,wstr->c_str());
(使い終わったらdelete [] str;)
・str → wstr
wstr=str;
std::wstringはPlatform::Stringよりはだいぶましだけど, printf的なものを使いたいときは結局wchar_t配列にしてsnwprintf_sとか使うしかない??
で、バイナリ列とか1バイト文字コード系とかを扱う標準的な方法が無く、何故かWindows::Security::Cryptography以下に使えるクラスがあるのでそれを使う。基本はArray
Array
に対してarr->Dataで実体のバイト列先頭へのポインタ, arr->Lengthで長さが取得出来、長さの範囲内で普通のポインタとして自由に読み書き出来る。
既にバイト列BYTE *data があってメモリもsizeバイト分確保されているときは、
ArrayReference
であたかもArray
・IBuffer^ bufからデータを取り出す
Array
Windows::Serurity::Cryptography::CryptographicBuffer::CopyToByteArray(buf,&arr);
でarrのインスタンスが作成されてデータが入って帰ってくる。CryptographicBufferはstaticなメソッドを集めたクラスなのでインスタンス化は必要ないというか出来ない。
arrは新規作成されるので、既にあるバイト列にArrayReferenceなどを使ってデータを移すことは出来ない。一度上の方法でarrを作ってからコピーするしかない。
・IBufferにデータを入れる
Windows::Storage::Streams::IBuffer^ buf=Windows::Serurity::Cryptography::CryptographicBuffer::CreateFromByteArray(arr);
こちらは読み出すだけなのでバイト列を使うときはArrayReferenceを用いればOK。
1バイト文字列は最後が\0のバイト列扱いで直接扱う関数は殆ど無い。Platform::String^(要するにUTF16) <--> UTF8 の変換だけはメソッドが用意されている。ちなみにただのASCIIというのも無いのでUTF8を代わりに用いる。
・Platform::String^ str → UTF8
IBuffer^ buf=Windows::Security::Cryptography::CryptographicBuffer::ConvertStringToBinary(str,Windows::Security::Cryptography::BinaryStringEncoding::Utf8);
最後のUtf8のところをUtf16LE, Utf16BEにするとリトルエンディアン、ビッグエンディアンのUTF16に変換する事も一応可能。
戻り値はIBufferなので、自分で使うには上記の方法でバイト列を取り出さないといけない。NULL終端されているかは未確認なので注意。
・IBuffer^ buf (中身はUTF8文字列) → Platform::String^
Platform::String^ str=Windows::Security::Cryptography::CryptographicBuffer::ConvertBinaryToString(Windows::Security::Cryptography::BinaryStringEncoding::Utf8,buf);
これも事前にIBufferに目的の文字列を入れておく必要がある。
UTF8以外のSJISとかEUCへの変換はクラス見つからなかったので仕方ないので従来通りのmbstowcs_s, wcstombs_sを用いる。例えばSJISにするならまず
size_t length=0;
_locale_t locale=_create_locale(LC_ALL,"japanese_jpn.932");
_wcstombs_s_l(&length,NULL,0,str->Data(),_TRUNCATE,locale);
とするとlengthに終端含めた必要サイズが入って戻ってくるので、
char *result=new char[length];
_wcstombs_s_l(&length,result,length,str->Data(),_TRUNCATE,locale);
として実際に変換する。ちなみにEUC-JPのロケールはjapanese_jpn.20932。
resultをchar *として確保せずにArray
逆は
size_t length=0;
_locale_t locale=_create_locale(LC_ALL,"japanese_jpn.932");
_mbstowcs_s_l(&length,NULL,0,(char*)src->Data,src->Length,locale);
wchar_t *buf=new wchar_t[length];
_mbstowcs_s_l(&length,buf,length,(char*)src->Data,src->Length,locale);
で、必要に応じてPlatform::String^ str=ref new Platform::String(buf); してPlatform::String^に変換しておく(この場合はその後すぐにbufはdeleteしてOK)。
SJIS,EUC以外にも変換出来るはずだけど、ロケール名をどうすればいいのかどこを調べても書いてないのでとりあえずHTTPにアクセスした戻り値のcharsetを見て動作を返るなどは難しそう。
フォルテールは小夜曲初回65151, コースは永久→AV→らぶすまショートで初回は36978,62436,87474。らぶすまロングは182651から。
この記事へのトラックバックURL: https://www.asmusic.jp/ASHARD/score/tb.cgi/yu-oishi/20121214手動トラックバック