I'm working with a Microsoft Kinect SDK where functions return BSTR. I need to get a QString or std::string.
Here's what I've tried:
BSTR bstr = s->NuiUniqueId();
// QString qs((QChar*)bstr, SysStringLen(bstr));
std::wstring ws(bstr);
ui->lblDetails->setText(QString::fromStdWString(ws));
With this solution the program crashes. With the line that is commented out I get "unresolved external symbol SysStringLen".
Is SysStringLen the way to go, but I need to add some additional libraries (wouldn't the API include it already) or is there another solution?
Additional question: why does Microsoft do it? I mean:
#if !defined(_NATIVE_WCHAR_T_DEFINED)
typedef unsigned short WCHAR;
#else
typedef wchar_t WCHAR;
#endif
typedef WCHAR OLECHAR;
typedef OLECHAR* BSTR;
typedef BSTR* LPBSTR;
What's the reason behind stuff like this? And even if they find it beneficial to use it internally, couldn't they just use normal char array or std::(w)string in the API to make other's life easier?
You can convert the BSTR object to char *, then convert it to QString. Here:
QString *getQStringFromBstr(BSTR bstrVal){
char *p= const_cast<char *>(_com_util::ConvertBSTRToString(bstrVal));
return new QString(p);
}
COM was designed to be Language-agnostic binary equalizer. Which means I could use a VB function in C++ and C++ function in, say, C#(with COM interop). This is the reason most of the strings and few functions were changed to language neutral strings IIRC.
Related
Now I am doing a Windows Metro App job, and I am developing a C++ component to get the input method's candidate List.
An issue occurs at the last step to output the result list. I can get each member of the candidate list, but the type is the "Bstr", to get them in the Metro App, I have to convert them into the type of "Platform::String".
How to convert Bstr to Platform::String?
I really appreciate any help you can provide.
The Platform::String constructor overloads make this very easy:
BSTR comstr = SysAllocString(L"Hello world");
auto wrtstr = ref new Platform::String(comstr);
To be perfectly complete, both BSTR and a WinRT string can contain an embedded 0. If you want to handle that corner case then:
BSTR comstr = SysAllocStringLen(L"Hello\0world", 11);
auto wrtstr = ref new Platform::String(comstr, SysStringLen(comstr2));
According to MSDN ([1],[2]) we have this definitions:
#if !defined(_NATIVE_WCHAR_T_DEFINED)
typedef unsigned short WCHAR;
#else
typedef wchar_t WCHAR;
#endif
typedef WCHAR OLECHAR;
typedef OLECHAR* BSTR;
So BSTR is of type wchar_t* or unsigned short*, or a null terminated 16-bit string.
From what I see from the documentation of Platform::String the constructor accepts a null-terminated 16-bit string as const char16*
While char16 is guaranteed represent UTF16, wchar is not.
UPDATE: As Cheers and hth. - Alf pointed out the line above isn't true for Windows/MSVC. I couldn't find any information on whether it is safe to cast between both types in this case. Since both wchar_t and char16_t are different integrated types I would still recommend to use std::codecvt to avoid problems.
So you should use std::codecvt to convert from wchar_t* to char16_t* and pass the result to the constructor of your Platform::String.
I am trying to convert a C++ library which is using widely DWORD, CString and BYTE in the program, and now I am converting the code from C++ Win32 library to linux program .
Also I am using openSUSE 12.3 and Anjuta IDE to do this , please help me which types I should use instead of mentioned types ?
I think I should use unsigned int for DWORD and string for CString and unsigned char instead of BYTE is it right ?
CString will not convert directly to std::string, but it is a rough equivalent.
BYTE is indeed unsigned char and DWORD is unsigned int. WORD is unsigned short.
You should definitely use typedef actual_type WINDOWS_NAME; to fix the code up, don't go through everywhere to replace the types. I would add a new headerfile that is called something like "wintypes.h", and include that everywhere the "windows.h" is used.
Edit for comment:
With CString, it really depends on how it is used (and whether the code is using what MS calls "Unicode" or "ASCII" strings). I would be tempted to create a class CString and then use std::string inside that. Most of it can probably be done by simply calling the equivalent std::string function, but some functions may need a bit more programming - again, it does depend on what member functions of CString are actually being used.
For LP<type>, that is just a pointer to the <type>, so typedef BYTE* LPBYTE; and typedef DWORD* LPDWORD; will do that.
DWORD = uint32_t
BYTE = uint8_t
These types are not OS specifics and were added to C++11. You need to include <cstdint> to get them. If you have an old compiler you could use boost/cstdint, which is header only.
Use std::string instead CString, but you will need to change some code.
With these changes your code should compile on both Windows and Linux.
I would suggest to use uint32_t and uint8_t from <stdint.h> for DWORD and BYTE and normal char * or const char * for strings (or the std:string class for C++).
Probably best thought is to use typedefs for existing code:
typedef unsigned char BYTE;
These can be changed easily.
If you rewrite code use char, int, long were useful and the (u)intX_t types, were you need a defined size.
typedef unsigned long DWORD;
typedef unsigned char BYTE;
CString -> maybe basic_string<TCHAR> ?
This question already has answers here:
What is `CString`?
(3 answers)
Closed 9 years ago.
Can someone explain me the difference and the relationship between the char * and CString?... Thanks.
There are few important differences.
char * is a pointer to char. Generally you can't say if it a single char, or a beginning of a string, and what is the length. All those things are dictated by program logic and some conventions, i.e. standard C functions, like to use const char * as inputs. You need to manage memory allocated for strings manually.
CString is a macro. Depending on your program compilation options, it can be defined to either the CStringA or CStringW class. There are differences and similarities.
The difference is that CStringAoperates with non-Unicode data (similar to char*), and CStringW is a Unicode string (similar to wchar_t*).
Both classes, however, are equivalent in the aspect of string manipulation and storage management. They are closer to the standard C++ std::string and std::wstring classes.
Apart from that, both CStringA and CStringW provide the capability to convert strings to and from Unicode form.
a CString will be an array of char and a char* will be a pointer into the array of char with which you can iterate the characters of the string.
Actually from MSDN:
CString is based on the TCHAR data type. If the symbol _UNICODE is defined for your program, TCHAR is defined as type wchar_t, a 16-bit character type; otherwise, it is defined as char, the normal 8-bit character type. Under Unicode, then, CString objects are composed of 16-bit characters. Without Unicode, they are composed of 8-bit char type.
CString is a class packed with different functionalities.. MSDN
char * is just a regular c++ data type.
CString is used mostly in MFC applications.
CString is a sequence of TCHAR-s rather then char*. The main difference is that if UNICODE is defined CString will be sequence of wchar. Actually depending on that macro CString will be tpyedef -ed either to CStringA or CStringW. Another major difference is that CString is a class while char* is simply a pointer to character.
Depending on the type of TCHAR, CString can be either CStringA or CStringW.
That said, CString is a wrapper over an array of chars, that enables you to easily treat that array of chars as a string, and operate on it in manners relevant to the string type.
For the relationship between them, here is something that illustrates it easily. You can convert between char * and CString like this:
CString str = "abc"; // const char[3] or char * to CString
and
const char * p = str.Get() // CString to const char *
A CString is a class and provides lots of functionalities that a char * doesnt. A char * is just a pointer to char or chars array.
A CString contains a buffer that is roughtly the same as a char * : LPTSTR GetBuffer( int nMinBufLength );
For the difference between LPTSTR and char * go here and here
CString is a wrapper class around a char* to provide some useful additional functions and to hide the memory allocation/deallocation from the user.
There is not much difference in performance terms so if you are using MFC classes, you might as well use a CString.
I'm writing a custom text-to-speech program that uses SAPI 5, and one problem I'm facing is that enumerating voices with SpEnumTokens and iterating over them produces CSpDynamicString objects.
My question is, how do I convert CSpDynamicString to char * so I could printf them?
It looks like I've to use some kind of text-conversion macro from ATL. I found an example that does this (given dstrDesc is CSpDynamicString):
CSpDynamicString dstrDesc;
SpGetDescription(voiceToken, &dstrDesc);
USES_CONVERSION;
printf("%s\n", W2T(dstrDesc));
However this only prints the first character of the voice name!
Any ideas?
CSpDynamicString implements an operator to convert to WCHAR* and also manages the LPWSTR pointer internally. So, W2T gets you LPTSTR pointer as printf argument. If you have a Unicode build, this is results still in a WCHAR* pointer and printf("%s"... expects CHAR* argument - this is where you can have the problem you are describing.
Try it this way:
CSpDynamicString dstrDesc;
SpGetDescription(voiceToken, &dstrDesc);
printf("%ls\n", (WCHAR*) dstrDesc);
I want to conver a tchar* to char * is this possible . if yes how to do it. I use unicode setting
A TCHAR is either a plain char or a wchar_t depending on your project's settings. If it's the latter, you would need to use WideCharToMultiByte with appropriate code page parameter.
You can't convert the pointer, you need to allocate a new string that is "char" instead of "wchar_t"
the most elegant way to do this is with the ATL conversion macros because it will hide all the allocation and called to the functions mentioned in the other comments
example
#include <atlbase.h>
#include <atlconv.h>
void YourFunction()
{
TCHAR wszHelloTchar = _T("Hello!\n");
USES_CONVERSION; // a macro required once before using T2A() and other ATL macros
// printf require a char*
// T2A converts (if necessary) the TCHAR string to char
printf( T2A( wszHelloTchar ) );
}
I find wcstombs works great for doing this sort of thing,