creating LPCTSTR conversion operator - visual-c++

Trying to create LPCTSTR conversion operator for my class:
AuthData::operator LPCTSTR() const
{
const char* k = "aaaa";
return k;
}
Error: return value type does not match the function type
Why it don't match?

If Unicode Character Set is enabled, LPCTSTR type is const wchar_t *.
#Edit
You can read about these types here:
https://softwareengineering.stackexchange.com/a/194768

In a Multi-Byte project, LPCTSTR is defined as LPCSTR, which is CONST CHAR*, so your code should compile (if it is in fact non-Unicode).
NEVER mix TCHARs with chars! At least - not without a conversion. Your declaration practically implies that TCHAR is defined as char, so why would you suggest to the readers that you are TCHAR-aware (since you are not)?

Related

C++ override quotes

Ok, so I'm using C++ to make a library that'd help me to print lines into a console.
So, I want to override " "(quote operators) to create an std::string instead of the string literal, to make it easier for me to append other data types to that string I want to output.
I've seen this done before in the wxWidgets with their wxString, but I have no idea how I can do that myself.
Is that possible and how would I go about doing it?
I've already tried using this code, but with no luck:
class PString{
std::string operator""(const char* text, std::size_t len) {
return std::string(text, len);
}
};
I get this error:
error: expected suffix identifier
std::string operator""(const char* text, std::size_t len) {
^~
which, I'd assume, want me to add a suffix after the "", but I don't want that. I want to only use ""(quotes).
Thanks!
You can't use "" without defining a suffix. "" is a const char* by itself either with a prefix (like L"", u"", U"", u8"", R"()") or followed by suffixes like (""s, ""sv, ...) which can be overloaded.
The way that wxString works is set and implicit constructor wxString::wxString(const char*); so that when you pass "some string" into a function it is essentially the same as wxString("some string").
Overriding operator ""X yields string literals as the other answer.

Bison bug when passing functions as arguments to yyparse?

I am in the process of re-writing a parser in order to make it reentrant. In that spirit, I am interested in passing a couple of functions to bison and then have bison pass them to lex also.
One of those functions is a callback which I use in my actions and the other one is the the function to be called by flex to get input data.
To do so, I have put this in my .y file:
%lex-param {void (*my_input)(void *, char*, int *, int)}
%parse-param {void (*my_input)(void *, char*, int *, int)}
%parse-param {void *(*my_callback)(void *, char *, int, struct YYLTYPE *, int, ...)}
Then, in my .l file I have declared:
#define YY_DECL int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner, void (*my_input)(void *, char*, int *, int))
The problem is that I think bison might have a bug when generating its code. When I try bo build, i get the following error:
tmp.tab.c: In function ‘yy_symbol_value_print’:
tmp.tab.c:4043: error: expected expression before ‘)’ token
If we visit that line we get this function:
static void
yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, yyscan_t scanner, void (*my_input)(void *, char*, int *, int), void *(*my_callback)(void *, char *, int, struct YYLTYPE *, int, ...))
{
FILE *yyo = yyoutput;
YYUSE (yyo);
YYUSE (yylocationp);
YYUSE (scanner);
YYUSE (int);
YYUSE (int);
if (!yyvaluep)
return;
YYUSE (yytype);
}
The first line with YYUSE(int) is the one throwing the error. As you can see, this function somehow receives the same arguments as yyparse, then it calls a macro called YYUSE() with the arguments received. I think that since two of my arguments are functions (with their arglist, as they have to be declared if I understand correctly) bison calls YYUSE() with the last argument of each of those function prototypes... as far as I know it should be USE(my_input) and USE(my_callback)...
I have a hard time believing this is really a bug, I mean, really, nobody has tried this until now? I find it hard to believe...
The YYUSE() calls are all over the generated files, even though I dont really know what they are for... So changing by hand is not really an option...
Has anybody done this successfully in the past? Is there something I am doing wrong?
Bison's parameter parser is a little primitive. It expects to see something like %param {type name}, and if it finds something more complicated, it may do the wrong thing. (type can be reasonably complicated; it can include const, *, and other such modifiers. But the name needs to be the last thing in the specification.)
This is documented in the Bison manual: (emphasis added)
Directive: %parse-param {argument-declaration} …
Declare that one or more argument-declaration are additional yyparse arguments. The argument-declaration is used when declaring functions or prototypes. The last identifier in argument-declaration must be the argument name.
A similar restriction applies to tagnames in a %union directive.
You can make your program more readable both for bison and for human readers by using typedefs:
Put this in a common header file:
typedef void (*InputFunction)(void *, char*, int *, int);
typedef void *(*CallbackFunction)(void *, char *, int, struct YYLTYPE *, int, ...);
Bison file:
%lex-param {InputFunction my_input}
%parse-param {InputFunction my_input} {CallbackFunction my_callback}
Flex file:
#define YY_DECL int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner, InputFunction my_input)
By the way, the intent of the YY_USE macro is to mark parameters as "used", even if they are not; this avoids compiler warnings in functions which happen not to use the arguments. It could be argued that it is the programmer's responsibility to ensure that arguments are either used or marked as unused, but that's not the approach bison happened to take. Regardless, non-conforming parameter declarations such as the one you provided will fail in other interesting ways, even without YY_USE.

How to convert string to LPSTR in WinAPI function which stores output in string

I am trying to store some contents into a string variable by passing it as a parameter in various types of Windows API functions which accepts variable like char *.
For example, my code is:-
std::string myString;
GetCurrentDirectoryA( MAX_PATH, myString );
Now how do I convert the string variable to LPSTR in this case.
Please see, this function is not meant for passing the contents of string as input, but the function stores some contents into string variable after execution. So, myString.c_str( ) is ruled out.
Edit: I have a workaround solution of removing the concept of string and replacing it with something like
char myString[ MAX_PATH ];
but that is not my objective. I want to make use of string. Is there any way possible?
Also casting like
GetCurrentDirectoryA( MAX_PATH, ( LPSTR ) myString );
is not working.
Thanks in advance for the help.
Usually, people rewrite the Windows functions they need to be std::string friendly, like this:
std::string GetCurrentDirectoryA()
{
char buffer[MAX_PATH];
GetCurrentDirectoryA( MAX_PATH, buffer );
return std::string(buffer);
}
or this for wide char support:
std::wstring GetCurrentDirectoryW()
{
wchar_t buffer[MAX_PATH];
GetCurrentDirectoryW( MAX_PATH, buffer );
return std::wstring(buffer);
}
LPTSTR is defined as TCHAR*, so actually it is just an ordinary C-string, BUT it depends on whether you are working with ASCII or with Unicode in your code. So do
LPTSTR lpStr = new TCHAR[256];
ZeroMemory(lpStr, 256);
//fill the string using i.e. _tcscpy
const char* cpy = myString.c_str();
_tcscpy (lpStr, cpy);
//use lpStr
See here for a reference on _tcscpy and this thread.
Typically, I would read the data into a TCHAR and then copy it into my std::string. That's the simplest way.

How to convert unsigned char to LPCTSTR in visual c++?

BYTE name[1000];
In my visual c++ project there is a variable defined name with the BYTE data type. If i am not wrong then BYTE is equivalent to unsigned char. Now i want to convert this unsigned char * to LPCTSTR.
How should i do that?
LPCTSTR is defined as either char const* or wchar_t const* based on whether UNICODE is defined or not.
If UNICODE is defined, then you need to convert the multi-byte string to a wide-char string using MultiByteToWideChar.
If UNICODE is not defined, a simple cast will suffice: static_cast< char const* >( name ).
This assumes that name is a null-terminated c-string, in which case defining it BYTE would make no sense. You should use CHAR or TCHAR, based on how are you operating on name.
You can also assign 'name' variable to CString object directly like:
CString strName = name;
And then you can call CString's GetBuffer() or even preferably GetString() method which is more better to get LPCTSTR. The advantage is CString class will perform any conversions required automatically for you. No need to worry about Unicode settings.
LPCTSTR pszName = strName.GetString();

C2664 error stream.write unsigned char *

ostream &stream;
stream.write(SomeUnsignedCharStar, intSize);
error C2664 cannot convert parameter 1 from const unsigned char * to const char *
Is there an overload write for const unsigned char *?
I do not want to change SomeUnsignedCharStar because it is everywhere in the legacy code I inherited. This was compiled on VC6 with no complain. I am slowly upgrading the code to VS2003 and then VS2010 evantually.
What is the easiest and cleanest fix?
You can cast this without any issues. Strict aliasing allows casting pointers between unsigned and signed versions of the same type, as well as casting from any type to const char*, so you're safe here.

Resources