I want to use the following code:
wstring s = L"GetLockCount " + g_SpeakerAlias.c_str();
MessageBoxW(NULL, unsignedinttowstring(iLockCount).c_str(), s, MB_OK);
The compiler tells me:
The expression must have an integer enumeration type or an enumeration type without range restriction
The way I try to concat the 2 wstrings seems to be wrong:
L"GetLockCount " + g_SpeakerAlias.c_str()
Here is the declaration:
wstring g_SpeakerAlias=L"SomeName";
The .c_str() is not necessary for the concatenation.
You need it only in the MessageBoxW as it expects LPCWSTR.
This is correct:
wstring s = L"GetLockCount " + g_SpeakerAlias;
MessageBoxW(NULL, unsignedinttowstring(iLockCount).c_str(), s.c_str(), MB_OK);
To be clear, the reason this works is because, while L"GetLockCount " is not a wstring (it's a wide-character C-style string literal, which is not a C++ wstring), g_SpeakerAlias is a wstring, and an overload exists for operator+ where the left side is a wchar_t* and the right is a wstring that produces another wstring. When you call .c_str(), it fails, because there is no overload covering wchar_t* + wchar_t*. Another solution would be to do wstring s = L"GetLockCount ";, then follow up with s += g_SpeakerAlias;; wstring constructs from the literal, then concats.
Related
Linux kernel call stack dump often includes function names that ends with ".isra.NNN" where NNN is some numbers. For example, see here and here.
What does that mean, what does the number signify?
isra is the suffix added to the function name when gcc option -fipa-sra compiler optimization being carried out.
From gcc manual:
-fipa-sra
Perform interprocedural scalar replacement of aggregates, removal of unused
parameters and replacement of parameters passed by reference by parameters passed
by value.
Enabled at levels -O2, -O3 and -Os.
All functions that are optimized under this option have isra appended to their names. I digged into gcc code and found out the function that was appending the string.
tree
clone_function_name (tree decl, const char *suffix)
{
tree name = DECL_ASSEMBLER_NAME (decl);
size_t len = IDENTIFIER_LENGTH (name);
char *tmp_name, *prefix;
prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
memcpy (prefix, IDENTIFIER_POINTER (name), len);
strcpy (prefix + len + 1, suffix);
#ifndef NO_DOT_IN_LABEL
prefix[len] = '.';
#elif !defined NO_DOLLAR_IN_LABEL
prefix[len] = '$';
#else
prefix[len] = '_';
#endif
ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, clone_fn_id_num++);
return get_identifier (tmp_name);
}
Here, argument 2, const char *suffix, is "isra" and notice at the bottom of the function macro ASM_FORMAT_PRIVATE_NAME which takes clone_fn_id_num++ as its 3rd argument. This is the arbitrary number found after "isra". This going by its name is the count of functions that are cloned under this compiler option (or may be a global counter that keeps track of all cloned functions).
If you want to understand more, search for modify_function in file gcc/tree-sra.c which in turn calls cgraph_function_versioning() which passes "isra" as its last argument.
i asked a question here involving C++ and C# communicating. The problem got solved but led to a new problem.
this returns a String (C#)
return Marshal.PtrToStringAnsi(decryptsn(InpData));
this expects a TCHAR* (C++)
lpAlpha2[0] = Company::Pins::Bank::Decryption::Decrypt::Decryption("123456");
i've googled how to solve this problem, but i am not sure why the String has a carrot(^) on it. Would it be best to change the return from String to something else that C++ would accept? or would i need to do a convert before assigning the value?
String has a ^ because that's the marker for a managed reference. Basically, it's used the same way as * in unmanaged land, except it can only point to an object type, not to other pointer types, or to void.
TCHAR is #defined (or perhaps typedefed, I can't remember) to either char or wchar_t, based on the _UNICODE preprocessor definition. Therefore, I would use that and write the code twice.
Either inline:
TCHAR* str;
String^ managedString
#ifdef _UNICODE
str = (TCHAR*) Marshal::StringToHGlobalUni(managedString).ToPointer();
#else
str = (TCHAR*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();
#endif
// use str.
Marshal::FreeHGlobal(IntPtr(str));
or as a pair of conversion methods, both of which assume that the output buffer has already been allocated and is large enough. Method overloading should make it pick the correct one, based on what TCHAR is defined as.
void ConvertManagedString(String^ managedString, char* outString)
{
char* str;
str = (char*) Marshal::StringToHGlobalAnsi(managedString).ToPointer();
strcpy(outString, str);
Marshal::FreeHGlobal(IntPtr(str));
}
void ConvertManagedString(String^ managedString, wchar_t* outString)
{
wchar_t* str;
str = (wchar_t*) Marshal::StringToHGlobalUni(managedString).ToPointer();
wcscpy(outString, str);
Marshal::FreeHGlobal(IntPtr(str));
}
The syntax String^ is C++/CLI talk for "(garbage collected) reference to a System.String".
You have a couple of options for the conversion of a String into a C string, which is another way to express the TCHAR*. My preferred way in C++ would be to store the converted string into a C++ string type, either std::wstring or std::string, depending on you building the project as a Unicode or MBCS project.
In either case you can use something like this:
std::wstring tmp = msclr::interop::marshal_as<std::wstring>( /* Your .NET String */ );
or
std::string tmp = msclr::interop::marshal_as<std::string>(...);
Once you've converted the string into the correct wide or narrow string format, you can then access its C string representation using the c_str() function, like so:
callCFunction(tmp.c_str());
Assuming that callCFunction expects you to pass it a C-style char* or wchar_t* (which TCHAR* will "degrade" to depending on your compilation settings.
That is a really rambling way to ask the question, but if you mean how to convert a String ^ to a char *, then you use the same marshaller you used before, only backwards:
char* unmanagedstring = (char *) Marshal::StringToHGlobalAnsi(managedstring).ToPointer();
Edit: don't forget to release the memory allocated when you're done using Marshal::FreeHGlobal.
When you build an app on Windows using TCHAR support, %s in _tprintf() means char * string for Ansi builds and wchar_t * for Unicode builds while %S means the reverse.
But are there any format specifiers that always mean char * string no matter if it's an Ansi or Unicode build? Since even on Windows UTF-16 is not really used for files or networking it turns out to still be fairly often that you'll want to deal with byte-based strings regardless of the native character type you compile your app as.
The h modifier forces both %s and %S to char*, and the l modifier forces both to wchar_t*, ie: %hs, %hS, %ls, and %lS.
This might also solve your problem:
_TCHAR *message;
_tprintf(_T("\n>>>>>> %d") TEXT(" message is:%s\n"),4,message);
You can easily write something like this:
#ifdef _UNICODE
#define PF_ASCIISTR "%S"L
#define PF_UNICODESTR "%s"L
#else
#define PF_ASCIISTR "%s"
#define PF_UNICODESTR "%S"
#endif
and then you use the PF_ASCIISTR or the PF_UNICODESTR macros in your format string, exploiting the C automatic string literals concatenation:
_tprintf(_T("There are %d ") PF_ASCIISTR _T(" over the table"), 10, "pens");
I found, that '_vsntprintf_s' uses '%s' for type TCHAR and works for both, GCC and MSVC.
So you could wrap it like:
int myprintf(const TCHAR* lpszFormat, va_list argptr) {
int len = _vsctprintf(lpszFormat, argptr); // -1:err
if (len<=0) {return len;}
auto* pT = new TCHAR[2 + size_t(len)];
_vsntprintf_s(pT, (2+len)*sizeof(TCHAR), 1+len, lpszFormat, argptr);
int rv = printf("%ls", pT);
delete[] pT;
return rv;
}
int myprintf(const TCHAR* lpszFormat, ...) {
va_list argptr;
va_start(argptr, lpszFormat);
int rv = myprintf(lpszFormat, argptr);
va_end(argptr);
return rv;
}
int main(int, char**) { return myprintf(_T("%s"), _T("Test")); }
I need to send multibyte char to a socket after appending '\n' but what I have is a const wchar_t*. How can I convert it?
If your question is how to actually manipulate the contents of a constant, then consider const_cast.
Appending an '\n' to a const wchar_t* string means you have to make a copy of the original string. Read this MS docs on how to use swprintf for that:
http://msdn.microsoft.com/en-us/library/ybk95axf%28VS.71%29.aspx
If your problem is the conversion, the WideCharToMultiByte Function is your friend:
http://msdn.microsoft.com/en-us/library/dd374130%28VS.85%29.aspx
You don't need to use direct newline characters to do this:
const wchar_t* original(L"original value");
std::wostringstream streamVal;
streamVal << original << std::endl;
const std::wstring modified(streamVal.str());
Going through a _bstr_t seems a pain but allows you to do the wide char to multibyte conversion pretty easily (small code). Include comsuppw.lib in the list of libraries in your project.
#include "comutil.h"
_bstr_t bstrVal(modified.c_str());
const char* multibytes((const char*)bstrVal);
std::cout << multibytes; // includes newline
How can I convert const wchar_t* to wchar_t*?
reinterpret_cast<const wchar_t*>(L"Test");
Should really work.
How to convert a char[256] to wstring?
update. here is my current code:
char testDest[256];
char *p= _com_util::ConvertBSTRToString(url->bstrVal);
for (int i = 0; i <= strlen(p); i++)
{
testDest[i] = p[i];
}
// need to convert testDest to wstring to I can pass it to this below function...
writeToFile(testDestwstring);
If your input is BSTR (as it seems to be) the data is already Unicode and you can just cast this directly to wstring as follows. _bstr_t has implicit conversions to both char* and wchar* which avoid the need for manual Win32 code conversion.
if (url->bstrVal)
{
// true => make a new copy - can avoid this if source
// no longer needed, by using false here and avoiding SysFreeString on source
const _bstr_t wrapper(url->bstrVal, true);
std::wstring wstrVal((const _wchar_t*)wrapper);
}
See here for more details on this area of Windows usage. It's easy to mess up the use of the Win32 API in this area - using the BSTR wrapper to do this avoids both data copy (if used judiciously) and code complexity.
MultiByteToWideChar will return a UTF-16 string. You need to specify the source codepage.