質問

高速化したいコードは次のとおりです。ADO レコードセットから値を取得し、それを char* に変換します。しかし、これは遅いです。_bstr_t の作成をスキップできますか?

                _variant_t var = pRs->Fields->GetItem(i)->GetValue();

                if (V_VT(&var) == VT_BSTR)
                {
                    char* p = (const char*) (_bstr_t) var;
役に立ちましたか?

解決

BSTR の最初の 4 バイトには長さが含まれます。ループして、Unicode の場合は 1 文字おきに、マルチバイトの場合はすべての文字を取得できます。ある種の memcpy または他の方法も機能するでしょう。IIRC、これは W2A またはキャスト (LPCSTR)(_bstr_t)

他のヒント

あなたの問題 (_bstr_t 内のメモリコピーの可能性を除く) は、UNICODE BSTR を ANSI char* に変換していることです。

スタック上で変換を実行する USES_CONVERSION マクロを使用できるため、より高速になる可能性があります。あるいは、可能であれば BSTR 値を Unicode のままにしてください。

変換する:

USES_CONVERSION;
char* p = strdup(OLE2A(var.bstrVal));

// ...

free(p);

覚えておいてください - OLE2A (およびその姉妹マクロ) から返される文字列は、スタックに割り当てられている文字列を返します - 囲んでいるスコープから返されると、それをコピーしない限り (当然、最終的には解放されますが) ガベージ文字列が残ります。

これにより、スタック上に一時ファイルが作成されます。

USES_CONVERSION;
char *p=W2A(var.bstrVal);

これは少し新しい構文を使用しており、おそらくより堅牢です。サイズは設定可能で、それを超えるとヒープが使用されるため、スタックに大量の文字列が置かれることがなくなります。

char *p=CW2AEX<>(var.bstrVal);
_variant_t var = pRs->Fields->GetItem(i)->GetValue(); 

フィールドを一度に収集しないようにすることで、この割り当てをより迅速に行うこともできます。Fields コレクションは、項目を名前で取得する必要がある場合にのみ使用してください。インデックスによってフィールドがわかっている場合は、代わりにこれを使用できます。

_variant_t vara = pRs->Collect[i]->Value;

ADO は VT_INTEGER をサポートしていないため、i は整数にはできないことに注意してください。したがって、long 変数を使用することもできます。

さて、私の C++ は少し錆びてきています...しかし、変換はあなたの問題ではないと思います。この変換では、コンパイラーに _bstr_t を char* とみなすように指示する以外、実際には何も行われません。次に、そのポインタのアドレスを p に割り当てるだけです。実際には何も「完了」していません。

GetValue からの取得が遅いだけではないでしょうか?

それとも、私の C++ は思っているよりも錆びているのでしょうか...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top