Visual StudioでC++(Windowsプログラム)を勉強しています。
BSTRという型について教えて下さい。
BSTRは先頭4バイトがその文字の長さが入っていると説明されているページがたくさんあります。
ただ、実際Visual StudioでBSTRの定義を追っていくと、
①typedef OLECHAR *BSTR;
↓
②typedef WCHAR OLECHAR;
と、ただのWCHARで、先頭4バイト云々などありませんでした。
人様のページですが、
https://www.artonx.org/collabo/backyard/?BasicString
にある「これはBSTRの実体の半分しか映していない。残り半分は、同じくwtypes.hの次の定義である。」
のくだりがありますが、この記載内容も理解できませんでした。
というのも、BSTR という型を使っているのに、_WORD_BLOB の定義など、上記のtypedef①②に関連しない型は全く使われないはずだと思うからです。
なにか根本的に勘違いしているのだと思うのですが、いくら調べてもわかりません。
わかりやすく教えてもらえないでしょうか。
よろしくおねがいします。
BSTRはただのWCHRではなく、typedefで定義されているようにWCHRへのポインタです。
確保領域の先頭にデータ長4バイトは正しく、SysAllocStringの戻り値は、このデータ長の直後のポインタとなります。↓ご参考です。
文字列というものは、正確には、C++の型システムに収めることができない代物です。
どういうことかというと、文字列とは長さがまちまちの文字配列だということです。
C++の型システムは、長さのきっちり決まったデータ構造を扱うことに長けていますが、長さがまちまちのものを扱うのは不得意なのです。
しかしC++の型システムというものはものすごく便利なものなので、どうにかして、文字列とC++の型システムとを合体させようとする苦肉の策が行われるのです。
BSTRの実体はらららさんが紹介しているページの通りだと思います(私は使ったことはないのですが)。
文字列の一般的な形式である「末尾に '\0' 」と、それに加えて、使うときにいちいち長さを数えなくても済むように、先頭に(いや先頭の直前に)文字列の長さを配置したものが、BSTRの実体というわけです。
では「BSTR」という型とは何か? これが苦肉の策です。
本来なら
struct BSTR {
unsigned int Length;
WCHAR arr [ # ];
};
とでもクラス定義を作りたいところですが、不定長なので「#」のところに定数を入れることができません。クラス定義として成り立たせることができないのです。
しかしBSTRという型をでっち上げて、それをクラス型のようなものとしてユーザーに使ってもらうということにすれば、ある程度扱いを楽にすることができます。
ユーザーがBSTRを使う場合は、BSTRとして渡されてきたポインタ(あ、ここが質問のポイントですかね?※)がBSTRの実体の内部にある文字列の先頭を指しているので、BSTRの実体のことなど何も考えずに、普通に文字列として扱うことができます。
※ BSTR は WCHAR の typedef ではなく、 WCHAR* の typedef です。文字ではなくポインタです。