3

SAFEARRAY の実装について知りたいです。

SAFEARRAY 構造体には、VT_I4(3) や VT_R4(4) などの要素の型情報を格納するために使用されるフィールドがないように思えますが、SafeArrayGetVartype 関数は正しい型を返します。

誰かが以下の MSDN ページにコメントし、上位ワードがcLocks型情報を保持していると述べています: MSDN の SAFEARRAY 構造

しかし、型ライブラリを介して VBA から DLL 関数に Long および Single 配列を渡すと、これらの配列の fFeature は両方とも 0x80 であり、cLocks は両方とも 0 であり、stll SafeArrayGetVartype は VT_I4(3) および VT_R4(4) を伝えることができます。

4

4 に答える 4

5

セーフ配列の作成方法によっては、バリアント型がSAFEARRAY構造体の前 (先頭からのオフセット -4) にメモリに格納される場合があります。FADF_HAVEVARTYPEflag infFeaturesは、型が使用可能かどうかを示します。

同様に、FADF_HAVEIIDは、GUID ( を参照SafeArrayCreateEx) が -16 のオフセットに格納され、 を介して使用できることを示しSafeArrayGetIIDます。FADF_HAVEVARTYPEFADF_HAVEIIDが同時に存在することはありません (そうしないVARTYPEと、GUIDと がメモリ内でオーバーラップするため) が、対応する機能フラグを検出したときに、または型のいずれかSafeArrayGetVartypeを合成するほどスマートです。VT_RECORDVT_DISPATCHVT_UNKNOWN

于 2013-09-13T12:55:10.007 に答える
2

手動で初期化することはありません。SAFEARRAY常に、SafeArrayCreateこの構造体にメモリを割り当てる を呼び出した結果です。SafeArray の内部データ構造に余分なバイトが割り当てられていると仮定しても安全だと思います。これは、拡張型情報を格納できる場所です。

于 2013-09-13T12:54:22.560 に答える
1

短縮版

varType = SafeArrayGetVarType(mySafeArray);

ロングバージョン

SAFEARRAYには、配列の内容を説明するのに役立つ機能メンバーがあります

2.2.30.10 SAFEARRAY (アーカイブ)

  • fFeatures:セクション2.2.9で指定されたビット フラグの組み合わせに設定する必要があります。

そして、あなたは相談します:

2.2.9 ADVFEATUREFLAGS 高度な機能フラグ (アーカイブ)

次の値は、SAFEARRAY (セクション 2.2.30.10) データ型のフィールド fFeatures で使用されます。

typedef  enum tagADVFEATUREFLAGS
 {
   FADF_AUTO = 0x0001,
   FADF_STATIC = 0x0002,
   FADF_EMBEDDED = 0x0004,
   FADF_FIXEDSIZE = 0x0010,
   FADF_RECORD = 0x0020,
   FADF_HAVEIID = 0x0040,
   FADF_HAVEVARTYPE = 0x0080,
   FADF_BSTR = 0x0100,
   FADF_UNKNOWN = 0x0200,
   FADF_DISPATCH = 0x0400,
   FADF_VARIANT = 0x0800
 } ADVFEATUREFLAGS;
  • FADF_RECORD: SAFEARRAY には UDT の要素が含まれている必要があります (セクション 2.2.28.1 を参照)。
  • FADF_HAVEIID: SAFEARRAY には MInterfacePointers 要素が含まれている必要があります。
  • FADF_HAVEVARTYPE: このビット フラグが設定されている場合、SAFEARRAY の cLocks フィールドの上位ワードには、配列の要素の型を記述する VARIANT 型定数が含まれている必要があります (セクション 2.2.7 および 2.2.30.10 を参照)。
  • FADF_BSTR: SAFEARRAY には BSTR 要素の配列が含まれている必要があります (セクション 2.2.23 を参照)。
  • FADF_UNKNOWN: SAFEARRAY には、IUnknown へのポインターの配列が含まれている必要があります。
  • FADF_DISPATCH: SAFEARRAY には、IDispatch へのポインターの配列が含まれている必要があります (セクション 3.1.4 を参照)。
  • FADF_VARIANT: SAFEARRAY には、VARIANT インスタンスの配列が含まれている必要があります。

そのため、FADF に応じて、対応するバリアント タイプを考え出すことができます。

機能フラグ 対応するバリアント タイプ
FADF_UNKNOWN VT_UNKNOWN
FADF_DISPATCH VT_DISPATCH
FADF_VARIANT VT_VARIANT
FADF_BSTR VT_BSTR
FADF_HAVEVARTYPE SafeArrayGetVarType(mySafeArray)

上記の作業 (FADF_BSTR を VT_BSTR に一致させるなど) はすべて、ヘルパー関数SafeArrayGetVarType ( archive )によってまとめられていることがわかります。

  • FADF_HAVEVARTYPEが設定されている場合、 SafeArrayGetVartypeは配列記述子に格納されている VARTYPE を返します。
  • が設定されている場合FADF_RECORDは、 を返しますVT_RECORD
  • が設定されている場合FADF_DISPATCHは、戻りますVT_DISPATCH
  • が設定されている場合FADF_UNKNOWNは、 を返しますVT_UNKNOWN

SafeArrayGetVartypeは、 IUnknownVT_UNKNOWNに基づく SAFEARRAY 型を返すことができない場合があります。呼び出し元は、SAFEARRAY 型のfFeaturesフィールドにフラグが設定されているかどうかをさらに確認する必要があります。FADF_UNKNOWN

于 2018-10-05T17:57:34.847 に答える