cannot convert const wchar_t* to const char* - c++11

ALL,
Can someone explain to me why this code:
std::wstring query1 = L"SELECT....";
res = mysql_query( m_db, m_pimpl->m_myconv.from_bytes( query1.c_str() ).c_str() );
gives me an error from the subject?
I do have -DUNICODE defined inside C++ options
I guess I just need a pair of fresh eyes.
Thank you.
It is on Gentoo Linux with gcc5.4.

This is a way to convert a unicode wide-character string to a const char*
char query_cstr[100];
size_t charsConverted;
wchar_t* unicode_query = L"SELECT * FROM table;";
wcstombs_s(&charsConverted, query_cstr, unicode_query, wcslen(unicode_query));
const char* query_const = query_cstr;
//Use query_const inside of mysql_query now that it's been converted to a const char*
I've run into trouble using the locale functions for various reasons. wcstombs_s() makes things a bit easier when converting unicode. Using c_str() on a std::wstring object will yield a const wchar_t* string, which is not what you want.

Related

Error: cannot convert parameter 1 from 'std::string' to 'System::String [duplicate]

I want to convert to std::string to System::String^ in Visual C++ environment. I know that we can convert System::String to std::string by the MarshalString Function as below:
void MarshalString ( String ^ s, string& os ) {
using namespace Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
I can't find the way to convert std::string to System::String but I found that System::String has constructor with argument as below :
System::String(Char* value, Int32 startIndex, Int32 length)
and i try to use code like below, but it can not give me a correct solution :
std::string str1 = "MyString";
System::String^ str = new System::String(str1.c_str(), 0, str1.length());
What wrong happen in my code?
Microsoft provide their C++ Suppport Library with Visual Studio to facilitate interaction between C++ and C++/CLI. That library provides the template function marshal_as which will convert a std::string to a System::String^ for you:
#include <msclr\marshal_cppstd.h>
std::string stdString;
System::String^ systemString = msclr::interop::marshal_as<System::String^>(stdString);

How do you convert a 'System::String ^' to 'TCHAR'?

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.

How do I convert a WCHAR * to a regular string?

So in Win32 API, I have my main function defined thus:
wmain(int argc, WCHAR* argv[])
I'm passing some arguments to it, and I'd like to execute a switch case based on the value of the argument, something like this.
wmain(int argc, WCHAR* argv[])
{
char* temp = argv[];
switch (temp) {
case "one": blah blah;
...
}
Of course, the temp=argv[] doesn't work, I'm looking for a suggestion to convert it. Right now I have an if-else-if thing going on, and it's VERY inefficient!
The reason I need to convert it is because I cannot execute a switch case on a WCHAR*.
Thanks for looking.
You can't execute a switch on a char* either. (But when you actually need to convert WCHAR* to char*, use WideCharToMultiByte)
You need to use if/else if with lstrcmpi, CompareString or some other string compare function.
Alternatively, use one of the parameter parser libraries like argtable or getopt
I am not sure if this is a good idea to do. A WCHAR* could contain unicode characters which cannot be mapped to a char* in a meaningful way. In case you want to ignore this, there is a forum post at http://www.codeguru.com/forum/showthread.php?t=336106 which has some suggestions for converting from WCHAR* to char*.
Try converting it from std::wstring to std::string, its easy, maybe there is a shorter way.
Convert WCHAR* to std::wstring using std::wstring constractor, and then use one of std::wstring method to convert to std::String
Here's a quick example I wrote some time ago.
Create a new win32 console application and select ATL support. Add this and compile/run...
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
// A _TCHAR is a typedef'd, depending on whether you've got a unicode or MBCS build
// ATL Conversion macros are documented here
// http://msdn.microsoft.com/en-us/library/87zae4a3(VS.80).aspx
// Declare USES_CONVERSION in your function before using the ATL conversion macros
// e.g. T2A(), A2T()
USES_CONVERSION;
TCHAR* pwHelloWorld = _T("hello world!");
wcout << pwHelloWorld << endl;
// convert to char
char* pcHelloWorld = T2A(pwHelloWorld);
cout << pcHelloWorld << endl;
cin.get();
return 0;
}
Of course, you can't switch on a string, but this should give you the info you need in order to read a WCHAR into a char. From there, you can convert to int easily enough..
Hope this helps ;)

How do I convert const wchar_t* to wchar_t or a multibyte char?

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 make String to const wchar_t* conversion function work under Windows and Linux

I work on a project written for MSVCC / Windows, that I have to port to GCC / Linux. The Project has its own String Class, which stores its Data in a QString from Qt. For conversion to wchar_t* there was originally this method (for Windows):
const wchar_t* String::c_str() const
{
if (length() > 0)
{
return (const wchar_t*)QString::unicode();
}
else
{
return &s_nullString;
}
}
Because unicode() returns a QChar (which is 16 Bit long), this worked under Windows as wchar_t is 16 Bit there, but now with GCC wchar_t is 32 Bit long, so that doesn't work anymore. I've tried to solve that using this:
const wchar_t* String::c_str() const
{
if ( isEmpty() )
{
return &s_nullString;
}
else
{
return toStdWString().c_str();
}
}
The problem with this is, that the object doesn't live anymore when this function returns, so this doesn't work eiter.
I think the only way to solve this issue is to either:
Don't use String::c_str() and call .toStdString().c_str() directly
Make GCC treat wchar_t as 16 bit type
Possibility one would mean several hours of needless work to me and I don't know if possiblity 2 is even possible. My question is, how do I solve this issue best?
I'd appreciate any useful suggestion. Thank you.
In my opinion, there are 2 ways :
convert QString to wchar_t* when needed
Let QString to store wchar_t* and return QString::unicode directly
These two functions can convert a QString to std::string and std::wstring
QString::toStdWString
QString::toStdString
To build QString as ucs4 :
#define QT_QSTRING_UCS_4
#include "qstring.h"
This can be used in qt3(qstring.h). I can't find the source of qt4.

Resources