Calling OutputDebugString in a C++ UWP project - c++

I'm trying to add a simple diagnostic output to a C++ UWP shared project akin to System.Diagnostics.Debug.WriteLine in C#. Following the documentation for OutputDebugString here and this solution here I've tried this:
char buf[1024];
sprintf(buf, "frequency = %f", (float)result);
OutputDebugString(buf);
but I get the compiler error
argument of type "char*" is incompatible with parameter of type "LPCWSTR"
How do I fix this?

A colleague advised me to add
#include "strsafe.h"
after any pre-compiled headers and then use this code instead
TCHAR buf[1024];
size_t cbDest = 1024 * sizeof(TCHAR);
StringCbPrintf(buf, cbDest, TEXT("frequency = %f"), (float)result);
OutputDebugString(buf);
I also needed to remember to swap the debugger to handle mixed code:

Here is what I use most of the time (notice the "L"):
#include <Windows.h>
OutputDebugString(L"Sarah Connor ?\n");

Related

E0167 error : C++ argument of type * is incompatible with parameter of type "FILE**"

i am very new to C and while working on examples in the book, i keep getting "C++ argument of type * is incompatible with parameter of type **" Error. I am using visual studio 2019 C++. Here is where i get the error when i use fopen_s:
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *inFile;
inFile = fopen_s("prices.dot","r"); /*Here is the line with an error*/
if (inFile == NULL)
{
printf("\nThis file does not existL");
printf("\nPlease make sure that this file currently exist");
exit(1);
}
printf("\nThe file has been succfully open for reading.");
return(0);
}
when i use "fopen" i get a warning which tells me to use fopen_s and when i do use fopen_s, i get the other error. I was wondering if i could get any help with this issue. Thank you!
If you google "MSDN fopen_s" and read the documentation on the Microsoft Developer Network, you will find that the function prototype is not identical to fopen():
errno_t fopen_s(
FILE** pFile,
const char *filename,
const char *mode
);
This means your code in that area would change to look like:
FILE *inFile;
errno_t errcode;
errcode = fopen_s(&inFile, "prices.dot","r");
if (errcode != 0) { /* do error handling, perhaps quit */ }
Alternately, you could continue to write old-style C code, and just use "fopen()" and at the top of your file, to shut MSVC compiler up, add the following #define:
#define _CRT_SECURE_NO_WARNINGS
Note, fopen_s() was added to the C 2011 standard, and is described in section K.3.5.2.1 -- meaning this is still portable C code on any modern C compiler.
Your book is probably older than 2011, and this function wasn't part of C at that time.

Why identifier 'strlen' is undefined?

I am writing a program in C++. When I use the strlen function, it is underlined by a red line. Although the project is built without errors. This is how I use this function. (By the way, strcpy is also underlined).
Exception::Exception(int _Line, char* _File, char* _Func, char* _Desc)
{
Line = _Line;
int size = strlen(_File) + 1;
File = new char[size];
strcpy(File, _File);
Func = new char[size];
strcpy(Func, _Func);
Desc = new char[size];
strcpy(Desc, _Desc);
}
And I declared <cstring> library at the beginning of the file. Please tell me how I can fix this?
As you can read up in the documentation for strlen(), strlen() is defined in string.h and the C++ counterpart std::strlen() is defined in cstring.
So to get rid of the error squiggles try adding one of the aforementioned headers.
#include <cstring>
...
std::strlen()
The system that underlines the code in the VS editor, called IntelliSense, does not use the same code as the compiler itself (or at least did not a few years ago when I used it last time). Sometimes it gets confused.
Try std::strlen instead, reorganizing the code, the includes, or something else.

OutputDebugString causing inconsistent errors

I have a problem that appears and disappears for mysterious reasons. A while back when I started the project I've found a fairly handy function that allows debug window output in VS2010. It worked great for a while.
Now it displays errors inconsistently. That means that sometimes the code will compile, sometimes it does not, and I can't find out why with code below causing the error. It seems almost random. Press compile, error, press compile again without changing anything sometimes error sometimes fine.
This is what it looks like with the error:
http://clip2net.com/clip/m0/1332710747-clip-29kb.png
and without:
http://clip2net.com/clip/m0/1332737362-clip-40kb.png
The culprit is OutputDebugString(buf);
Error doesn't occur with that line commented out.
I am looking to solve this problem, i simply need a way to output text into debug window (output), and am looking for a simple, stable solution. Or perhaps there is a way to make this function work. I am kind of stuck.
I would appreciate it if you could share how you do it.
The code is:
#pragma once
#ifndef _XDEBUG_H_
#define _XDEBUG_H_
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
class XDebug
{
public:
static void __cdecl odprintf(const wchar_t *format, ...){
wchar_t buf[4096], *p = buf;
va_list args;
int n;
va_start(args, format);
n = _vsnwprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
va_end(args);
p += (n < 0) ? sizeof buf - 3 : n;
while ( p > buf && isspace(p[-1]) )
*--p = '\0';
*p++ = '\r';
*p++ = '\n';
*p = '\0';
OutputDebugString(buf);
}
};
#endif
OutputDebugString is defined in Windows.h. You need to include that header to be able to use that function.
It looks like you haven't done:
#include <windows.h>
The OutputDebugString function is part of the Windows API.

GetCurrentDirectory buffer doesn't return the right value

I have an issue with GetCurrentDirectory(), and i don't really understand why. The thing i don't understand is that it works for XP but not for Seven (or at least on my computer). There is my code:
char dir_name[1024]; // as a global variable
int get_files() {
// ...
DWORD dwRet;
dwRet = GetCurrentDirectory(MAX_PATH, dir_name);
printf("%s\n",dir_name);
printf("%d\n",dwRet);
//...
}
This code will return:
printf("%s\n",dir_name); -> return "c"
printf("%d\n",dwRet); -> 42 (which is the right length of the string that should be returned)
I don't understand why dir_name only takes the value "c".
I think, the result is Unicode in Windows Seven! and after each ascii character of this function there is zero. And you are printing it by printf. You should use wide-char functions in your program. Like wprintf.
Try below code: (Tested in Visual Studio 2008 + Windows 7)
#include <stdio.h>
#include <windows.h>
#include <wchar.h>
WCHAR dir_name[1024]; // as a global variable
int get_files()
{
// ...
DWORD dwRet;
dwRet = GetCurrentDirectory(MAX_PATH, dir_name);
wprintf(L"%s\n", dir_name);
printf("%d\n", dwRet);
//...
return 0;
}
Im not sure, but could it be GetCurrentDirectory() returns 2-byte chars under win7?
In such case you'll be getting a 0 in each second bytes of the char array returned.
So you should use a wide-char aware version of the printf() function such as wprintf().
Also I wonder whether the compiler wouldn't have warned you about something being wrong regarding types.
what compiler are you using? Under Visual C++ 2005, GetCurrentDirectory is a macro that resolves to GetCurrentDirectoryW if UNICODE macro is defined and to GetCurrentDirectoryA otherwise. Do you have UNICODE defined by any chance?

ReadFile Win32 API

i want to read a file.. but.. when i debug my program it runs but a pop up appears and says system programming has stopped working and in the console, it`s written that Press enter to close the program. my code is ::
// System Programming.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hin;
HANDLE hout;
TCHAR buff[20]= {'q','2','3'};
TCHAR buff2[20]={'a','v'};
hin = CreateFile(_T("Abid.txt"),GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hin == INVALID_HANDLE_VALUE)
{
cout<<"error";
}
WriteFile(hin,buff,40,0,NULL);
CloseHandle(hin);
hout = CreateFile(_T("Abid.txt"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hout == INVALID_HANDLE_VALUE)
{
cout<<"error";
}
ReadFile(hout,buff2,40,0,NULL);
CloseHandle(hout);
return 0;
}
According to MSDN, lpNumberOfBytesWritten paremeter can be NULL only when the lpOverlapped parameter is not NULL. So the calls should be
DWORD nWritten;
WriteFile(hin, buff, 40, &nWritten, NULL);
and
DWORD nRead;
ReadFile(hout, buff2, 40, &nRead, NULL);
Also, rename hin and hout.
Others have already answered your question. This is about the code.
// Your code:
// System Programming.cpp : Defines the entry point for the console application.
//
Just remove that comment. It isn't true. :-) The entry point for your program is where the machine code starts executing, and with the Microsoft toolchain it's specified by the /entry linker option.
Note that Microsoft's documentation is generally confused about entry points, e.g. it has always, one way or other, documented incorrect signature for entry point.
It's one of the most infamous Microsoft documentation errors, and, given that it's persisted, in various forms, for 15 years, I think it says something (not sure exactly what, though).
// Your code:
#include "stdafx.h"
You don't need this automatically generated header. Instead use <windows.h>. A minimal way to include <windows.h> for your program would be
#undef UNICODE
#define UNICODE
#include <windows.h>
For C++ in general you'll want to also make sure that STRICT and NOMINMAX are defined before including <windows.h>. With modern tools at least STRICT is defined by default, but it doesn't hurt to make sure. Without it some of declarations won't compile with a C++ compiler, at least not without reinterpret casts, e.g. dialog procedures.
// Your code:
#include "iostream"
using namespace std;
Almost OK.
Do this:
#include <iostream>
using namespace std;
The difference is where the compiler searches for headers. With quoted name it searches in some additional places first (and that's all that the standard has to say about it). With most compilers those additional places include the directory of the including file.
// Your code:
int _tmain(int argc, _TCHAR* argv[])
Oh no! Don't do this. It's a Microsoft "feature" that helps support Windows 9.x. And it's only relevant when you're using MFC linked dynamically and you're targeting Windows 9.x; without MFC in the picture you'd just use the Microsoft Unicode layer.
Area you really targeting Windows 9.x with an app using dynamically linked MFC?
Instead, do ...
int main()
... which is standard, or use the Microsoft language extension ...
int wMain( int argc, wchar_t* argv[] )
... if you want to handle command line arguments the "easy" way.
// Your code:
{
HANDLE hin;
HANDLE hout;
TCHAR buff[20]= {'q','2','3'};
TCHAR buff2[20]={'a','v'};
The TCHAR stuff is just more of that MFC in Windows 9.x support stuff.
Apart from being totally unnecessary (presumably, you're not really targeting Windows 9.x, are you?), it hides your intention and hurts the eyes.
Did you mean ...
char buff[20] = {'q', '2', '3'};
... perhaps?
// Your code:
hin = CreateFile(_T("Abid.txt"),GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hin == INVALID_HANDLE_VALUE)
{
cout<<"error";
}
As others have mentioned, OPEN_EXISTING isn't logical when you're creating the file, and the count pointer argument can't be 0 for your usage.
When using <windows.h>, with UNICODE defined as it should be, the filename argument should be specifed as L"Abid.txt".
Cheers & hth.,
The problem is that you're passing a NULL pointer in for the lpNumberOfBytesWritten/lpNumberOfBytesread parameter. While this is an optional parameter, there's a condition:
This parameter can be NULL only when the lpOverlapped parameter is not NULL
Also, you may have the size of your buffers wrong:
WriteFile(hin,buff,40,0,NULL); // says that buff has 40 bytes
ReadFile(hout,buff2,40,0,NULL); // says that buff2 has 40 bytes
But if you're compiling for ANSI instead of UNICODE, these will only be 20 bytes in size.
You should probably use sizeof(buff) and sizeof(buff2) instead.
Assuming your initial code attempts to create the file as a new file, then you cannot use OPEN_EXISTING, you have to use OPEN_ALWAYS (or some other creational variant) on this call.
The OPEN_EXISTING usage for readback will be OK.
btw once this is fixed the WriteFile calls causes an access violation, as you are trying to write more bytes that your array contains.