4

这是我想加快速度的代码。它从 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;
4

5 回答 5

3

您的问题(除了 _bstr_t 内存副本的可能性)是您将 UNICODE BSTR 转换为 ANSI char*。

您可以使用在堆栈上执行转换的 USES_CONVERSION 宏,因此它们可能会更快。或者,如果可能,将 BSTR 值保留为 unicode。

转换:

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

// ...

free(p);

记住 - 从 OLE2A(及其姊妹宏)返回的字符串返回一个分配在堆栈上的字符串 - 从封闭范围返回并且你有垃圾字符串,除非你复制它(并最终释放它,显然)

于 2008-09-22T21:33:05.080 回答
3

BSTR 的前 4 个字节包含长度。如果是 unicode,则可以循环并获取每个其他字符,如果是多字节,则可以获取每个字符。某种 memcpy 或其他方法也可以。IIRC,这可能比W2A或铸造更快(LPCSTR)(_bstr_t)

于 2008-09-23T00:36:15.887 回答
2

这会在堆栈上创建一个临时的:

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

这使用了稍微更新的语法,并且可能更健壮。它具有可配置的大小,超过该大小它将使用堆,因此它避免将大量字符串放入堆栈:

char *p=CW2AEX<>(var.bstrVal);
于 2008-09-22T21:32:47.217 回答
0
_variant_t var = pRs->Fields->GetItem(i)->GetValue(); 

您还可以通过避免将字段集合放在一起来更快地完成此分配。当您需要按名称检索项目时,您应该只使用 Fields 集合。如果您通过索引知道字段,则可以改用它。

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

注意 i 不能是整数,因为 ADO 不支持 VT_INTEGER,因此您不妨使用 long 变量。

于 2010-03-04T12:15:23.653 回答
-2

好的,我的 C++ 有点生锈了……但我不认为转换是你的问题。除了告诉编译器将 _bstr_t 视为 char* 之外,这种转换实际上并没有做任何事情。然后,您只需将该指针的地址分配给 p。实际上什么都没有“完成”。

你确定这不仅仅是从 GetValue 获取东西的速度慢吗?

还是我的 C++ 比我想象的更生疏……

于 2008-09-22T21:34:17.730 回答