在最佳时间从_variant_t获取char *
-
02-07-2019 - |
题
这是我想要加速的代码。它从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 ++比我想象的更生气......
不隶属于 StackOverflow