VBScriptはCOMオートメーションと呼ばれるレイトバインディングテクノロジを使用します。このテクノロジは、COMオブジェクトへのすべてのメソッド呼び出しを単一の汎用メソッド呼び出し、つまりIDISPATCH:Invoke(...)
によってルーティングします。 (Visual Basicでは、変数As Object
をDimして呼び出しを行うときに同じ技術を使用します)
は、バリアントを操作するには、COMヘッダは、私がここに使用しますこれは、便利なマクロと定数を提供してくれます(VT_BOOL、V_VT()、V_BOOL()は、FAILED()):
// I usually initialize to Empty at the top of the method,
// before anything can go wrong.
VariantInit(bAllShared);
// My bad -- ignore the above. It applies to [out] parameters only.
// Because bAllShared is passed as a [ref] variable,
// calling VariantInit() on them would leak any preexisting value.
// Instead, read the incoming value from the variable (optional),
// then "clear" them before storing new values (mandatory):
// This API figures out what's in the variable and releases it if needed
// * Do nothing on ints, bools, etc.
// * Call pObj->Release() if an Object
// * Call SysFreeString() if a BSTR
// etc
VariantClear(bAllShared);
それらを初期化します。以前の値がリークする原因になります。 VARIANT
を読むには
:
// Always check that the value is of the proper type
if (V_VT(bAllShared) == VT_BOOL) {
// good
bool myArg = (V_BOOL(bAllShared) == VARIANT_TRUE);
} else {
// error, bad input
}
またはより良い、あなたは常にVBScriptのユーザーが「真」と1がVARIANT_TRUEと同じように動作することを期待するので、自分自身を変換してみてください。幸いなことに、COMは、そのための素晴らしいユーティリティAPIを持っています
// This is exactly the same thing that VBScript does internally
// when you call CBool(...)
VARIANT v;
VariantInit(&v);
if(FAILED(VariantChangeType(&v, &bAllShared, 0, VT_BOOL))
{
// error, can't convert
}
bool myArg = (V_BOOL(v) == VARIANT_TRUE);
VARIANT
に書き込むために:
今 // Internal working value
bool isShared;
...
// set the Variant's type to VARIANT_BOOL
V_VT(bAllShared) = VT_BOOL;
// set the value
V_BOOL(bAllShared) = (isShared ? VARIANT_TRUE : VARIANT_FALSE);
、第二の問題は、あなたのサンプルVBScriptコードである:
m_oReportManager.GetReportAccessRights _
CLng(m_lRptCod), CBool(bAllShared), CBool(bAllRunOnly), CBool(bAllCopy)
引数CBool(something)
などを渡すので、実際の変数ではなく一時変数(CBool(...)の戻り値)を戻していますbAllShared
などです。正しいC++実装であっても、返された値は中間値として破棄されます。
次のようなメソッドを呼び出す必要があります:そうですね
m_oReportManager.GetReportAccessRights _
CLng(m_lRptCod), bAllShared, bAllRunOnly, bAllCopy
を。値を「変換する」必要はありません。 VBScriptはあなたが何をしても常にVARIANT
を渡します。上記のように、bool型などの入力パラメータであっても、ATLはCBool()
を呼び出します。
(ATLはCBoolを()呼び出し?はい?VBScript関数ということではなく、CBoolは()VariantChangeType()
周りの単純なラッパーであり、それはATLがあなたのために呼ぶものです)
編集: VBScriptは[out]
パラメータをサポートしていません。 [ref]
パラメータのみ。 C++でパラメータを[out]
と宣言しないでください。メソッドが[out]
パラメータを宣言する場合、VBScriptは[ref]
パラメータのように動作します。これにより、パラメータの入ってくる値が漏れることになります。 [out]引数の1つがもともと文字列を持っていた場合、そのメモリはリークされます。オブジェクトがあれば、そのオブジェクトは決して破壊されません。
恐ろしい返信です!ありがとう。 – ssorrrell
+1は非常に徹底的な答えです。 – Tester101