这是我想要加速的代码。它从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,则可以遍历并获取所有其他字符,如果是多字节,则可以获取每个字符。某种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,所以你也可以使用一个长变量。

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

你确定从GetValue获取东西不是很慢吗?

或者我的C ++比我想象的更生气......

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top