Getting a char* from a _variant_t in optimal time

a 夏天 提交于 2020-01-24 06:26:09

问题


Here's the code I want to speed up. It's getting a value from an ADO recordset and converting it to a char*. But this is slow. Can I skip the creation of the _bstr_t?

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

                if (V_VT(&var) == VT_BSTR)
                {
                    char* p = (const char*) (_bstr_t) var;

回答1:


The first 4 bytes of the BSTR contain the length. You can loop through and get every other character if unicode or every character if multibyte. Some sort of memcpy or other method would work too. IIRC, this can be faster than W2A or casting (LPCSTR)(_bstr_t)




回答2:


Your problem (other than the possibility of a memory copy inside _bstr_t) is that you're converting the UNICODE BSTR into an ANSI char*.

You can use the USES_CONVERSION macros which perform the conversion on the stack, so they might be faster. Alternatively, keep the BSTR value as unicode if possible.

to convert:

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

// ...

free(p);

remember - the string returned from OLE2A (and its sister macros) return a string that is allocated on the stack - return from the enclosing scope and you have garbage string unless you copy it (and free it eventually, obviously)




回答3:


This creates a temporary on the stack:

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

This uses a slightly newer syntax and is probably more robust. It has a configurable size, beyond which it will use the heap so it avoids putting massive strings onto the stack:

char *p=CW2AEX<>(var.bstrVal);



回答4:


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

You can also make this assignment quicker by avoiding the fields collection all together. You should only use the Fields collection when you need to retrieve the item by name. If you know the fields by index you can instead use this.

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

Note i cannot be an integer as ADO does not support VT_INTEGER, so you might as well use a long variable.




回答5:


Ok, my C++ is getting a little rusty... but I don't think the conversion is your problem. That conversion doesn't really do anything except tell the compiler to consider _bstr_t a char*. Then you're just assigning the address of that pointer to p. Nothing's actually being "done."

Are you sure it's not just slow getting stuff from GetValue?

Or is my C++ rustier than I think...



来源:https://stackoverflow.com/questions/117755/getting-a-char-from-a-variant-t-in-optimal-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!