Getting char * from _variant_t at optimal time

Here is the code I want to speed up. It gets the value from the ADO recordset and converts it to char *. But it is slow. Can I skip creating _bstr_t?

_variant_t var = pRs->Fields->GetItem(i)->GetValue(); if (V_VT(&var) == VT_BSTR) { char* p = (const char*) (_bstr_t) var; 
+4
source share
5 answers

The first 4 bytes of the BSTR contain the length. You can loop and get every other character if unicode or every character if it is multibyte. Some kind of memcpy or other method will work. IIRC, it can be faster than W2A or cast (LPCSTR)(_bstr_t)

+3
source

Your problem (besides being able to copy to memory inside _bstr_t) is that you are converting UNICODE BSTR to ANSI char *.

You can use USES_CONVERSION macros that do the conversion on the stack, so they can be faster. Alternatively, save the BSTR value as unicode, if possible.

to convert:

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

remember - the line returned from OLE2A (and its macros with the sister) returns the line allocated on the stack - returns from the enclosing area, and you have a garbage line if you do not copy it (and, ultimately, free it) p >

+3
source

This creates a temporary place on the stack:

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

This uses a slightly newer syntax and probably more robust. It has a custom size, beyond which it will use a bunch so that it does not push massive strings onto the stack:

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

You can also complete this task faster by avoiding combining fields. You should use the Fields collection only when you need to get an element by name. If you know the fields by index, you can use this.

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

Note. I cannot be an integer since ADO does not support VT_INTEGER, so you can use a long variable.

0
source

Well, my C ++ is getting a little rusty ... but I don't think conversion is your problem. This conversion actually does nothing but tell the compiler to consider _bstr_t a char *. Then you just assign the address of this pointer to p. Nothing is actually "done."

Are you sure this is not just slow getting material from GetValue?

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

-2
source

Source: https://habr.com/ru/post/1277043/


All Articles