"unknown error" from std::error_code on Windows - c++

I have a strange problem with system error messages obtained from std::error_code on Windows. When I build and run test program 1 (see below) using my locally installed Visual Studio, error messages for all system error codes come out as "unknown error". On the other hand, when building and running the same program on the same version of Visual Studio through Godbolt / Compiler Explorer, proper error messages are produced (see test program 1 and output below).
I tested this with Visual Studio 2022 version 17.3.3 (MSVC 19.33) on Windows 10.
I am using the community version of Visual Studio.
I have tried to build locally using the developer command prompt (cl test.cpp), using a Visual Studio console project (all settings at default), and using a Visual Studio CMake project (all settings at default). It makes no difference. In all cases, all error messages come out as "unknown error".
I am not experienced with Visual Studio, so I may definitely be making a very basic mistake.
Any advice as to how I can further diagnose the problem is also welcome.
Output from test program 1 (see below) when built and run through Godbolt / Compiler Explorer:
message = 'The directory is not empty.' (193331629)
Output from test program 1 (see below) when built and run locally:
message = 'unknown error' (193331629)
Output from test program 2 (see below) when built and run locally:
message = 'The directory is not empty.' (193331629)
Test program 1:
#include <windows.h>
#include <system_error>
#include <stdio.h>
int main()
{
std::error_code ec(ERROR_DIR_NOT_EMPTY, std::system_category());
printf("message = '%s' (%lld)\n", ec.message().c_str(), static_cast<long long>(_MSC_FULL_VER));
}
Test program 2 (for contrast):
#include <windows.h>
#include <stdio.h>
int main()
{
char buffer[256];
DWORD len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, ERROR_DIR_NOT_EMPTY, 0, buffer, 255, NULL);
while (len > 0 && (buffer[len - 1] == '\n' || buffer[len - 1] == '\r'))
--len;
buffer[len] = '\0';
printf("message = '%s' (%lld)\n", buffer, static_cast<long long>(_MSC_FULL_VER));
}

Ok, the problem in my case is that the system locale is set to "en-GB" and not "en-US".
If I pass language identifier 2057 (en-GB) to FormatMessage() I get no error message, but if I pass 1033 (en-US), I do.
So far, I have not been able to change the system-level locale, but even if it can be done, it seems rather suboptimal that system error messages fail to work if my system locale is set to "en-GB".
I wonder if there is a rational idea behind this behavior, or if it is just plain broken.
In any case, the solution in my case, I think, is to introduce a custom error category that invokes FormatMessage() with a language identifier of 0 (see https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage), and then forward to the native system error categeory in the functions that deal with mapping to generic error condition.

Related

printf doesn't print any message from dll library

I have problem in printing messages from ".dll" library created in visual studio 2019.
I don't receive any errors or warnings. printf or std::cout just do nothing. Everything worked fine in visual studio 2010. I tried to compare project properties between vs2019 and vs2010 versions. But I didn't notice anything that may effect output.
Here is simple example that shows how I expect to receive messages from this library:
#define DLLReturnType __declspec(dllexport)
DLLReturnType int add3DArraysLib(int value)
{
printf("Received value - %d", value);
return value + 1;
}
My suggestion is to change your "SubSystem" to be Console (/SUBSYSTEM:CONSOLE) then to see the printf messages on Visual Studio Output window.
One more thing, #include <iostream> is necessary !
Property setting is here:

"CL.exe" Not Compiling C++ in stand alone project

How to fix "CL.exe" Not Compiling C++??
I have created a standalone python project on my desktop, keep in mind that I'm not using Visual Studio, I am in fact using pythontowin. I would like to compile a C++ file into a DLL to use for my python project. But I am getting weird unexplained errors when trying to compile with cl.exe.
Here is my C++ file.
#include <Windows.h>
#include <iostream>
using namespace std;
void Thread() {
cout < "Hello World" < endl;
Sleep(1000);
}
BOOL DllMain(HINSTANCE hDll,DWORD dwReason, LPVOID) {
if (dwReason == DLL_PROCESS_ATTACH) {
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Thread, 0, 0, 0);
}
return TRUE;
}
Command used for cl.exe: cl.exe /std:c++14 /LD ./../LibraryXdll.cpp
And this is the error I am getting: fatal error C1034: Windows.h: no include path set
If anyone could solve this error I would be very thankful and I can finish off my project thanks for the help. Regards RanOutOfQuestions!
Taking up on Tadman's comment:
It looks like you didn't set up your environment variables for use of cl.exe
If you have gotten cl.exe, you should also have a Bat-File called vcvarsall.bat or vcvars32.bat / vcvars64.bat. In case of a default Visual studio installation these can be found under "Program Files (x86)\Microsoft Visual Studio\version number\produkt type, e.g. community\VC\Auxiliary\Build".
Run the appropriate version of vcvars... (32 or 64 bit, or specifiy the flag for vcvarsall, see docs), and your include paths for THAT SESSION will be set (inside that terminal, if you close it the changes are lost again and you have to call vcvars again next time).
EDIT: Microsoft documentation on vcvars
You can work around that Reset by calling vcvars every time before executing the compiler, though this isn't a beautiful solution

Error Loading Enclave: Couldn't open file with CreateFile()

I'm trying to write a simple SGX project for a start. So I have this main host application routine that I've pretty much copied from Lars Richter's blog:
#define ENCLAVE_FILE _T("Enclave.signed.dll")
#include <tchar.h>
#include <cstdio>
#include "sgx_urts.h"
#include "Enclave_u.h"
int main()
{
sgx_enclave_id_t eid;
sgx_status_t ret = SGX_SUCCESS;
sgx_launch_token_t token = { 0 };
int updated = 0;
ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL);
if (ret != SGX_SUCCESS) {
printf("\nApp: error %#x, failed to create enclave.\n", ret);
}
scanf("\n");
return 0;
}
It compiles fine (I'm using the Intel C++ 17.0 compiler with Visual Studio 2015) but it doesn't load the enclave. I get the following error message:
[sgx_create_enclavew ..\urts\win\urts.cpp:195] Couldn't open file with CreateFile()
App: error 0x200f, failed to create enclave.
Go to app_test_save project setting. Under Debugging, change working directory to $(SolutionDir)Debug. This answer assumes that both projects app_test_save and enclave_test_save belong to the same solution.
As Neil pointed out, sgx_create_enclave couldn't find the dll when the program was being run from within Visual Studio's debugger. It worked fine when I directly ran the executable in the "Debug" folder.
So a simple trick to make it work in both settings is to do the following:
#define ENCLAVE_FILE _T("../Debug/Enclave.signed.dll")
According to this : https://software.intel.com/en-us/forums/intel-software-guard-extensions-intel-sgx/topic/623738
If you are using the Local SGX Debugger, Please make sure change the "current working directory" pointing to $(OutDir) instead of $(ProjectDir).
Configuration Properties --> Debugging --> Working Directory --> $(OutDir).
Error is basically means it could not locate your .dll file.
Do dir /a/s to find Enclave.signed.dll then change the name appropriately.
When you create enclave it will generate signed.dll file. If your enclave name is Enclave12 then the DLL name is Enclave12.signed.dll. You fix this then you should be good to go.

map/set iterators incompatible error using OpenEXR and compiled in MSVC Debug mode

I have a problem that I can't figure out. My project using the OpenEXR library is perfectly working on the Linux platform. It has to be compilable also in Visual Studio 2015. Hence I'm trying to port it. I have successfully compiled and installed OpenEXR 2.2.0 release (downloaded from the official site, following instructions at GitHub). Unfortunately I'm hitting several issues with my code. One of them can be simplified to the following small snippet:
#include <OpenEXR/ImfInputFile.h>
#include <OpenEXR/ImfHeader.h>
int main(int argc, char * argv[]) {
Imf::InputFile exr_file("test.exr");
const Imf::Header & exr_header = exr_file.header();
// e.g. this fails at debug assertion: map/set iterators incompatible
bool test1 = exr_header.begin() != exr_header.end();
// or this gets stuck somehow and consuming CPU, the program doesn't continue
bool test2 = exr_header.begin() != exr_header.begin();
return 0;
}
When it is compiled in the Release mode it seems to be fine (at least for the snippet, my project has some other issues which I suspect to be related). But in the Debug mode, which I need to debug my project, strange things occur. The first test ends with a debug assertion:
Debug Assertion Failed!
Program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll
File: c:\program files (x86)\microsoft visual studio 14.0\vc\include\xtree
Line: 326
Expression: map/set iterators incompatible
The second one (when the first is commented out) gets stuck and the program seems like to be in an endless loop. I don't understand why.
Please, can somebody help me? I'm using Visual Studio Community 2015 if that matters.

Visual C++ err: RegGetValueA could not be located

Attempting to write a simple registry-check script in Visual Studio 2010, running on XP SP3 x86.
No errs are thrown on build, but on debug the program exits with the following error:
The procedure entry point RegGetValueA
could not be located in the dynamic
link library ADVAPI32.dll
Here is the entire code of the program.
// #define _WIN32_WINNT 0x0501
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[])
{
long reg = RegQueryValueEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", NULL,NULL,NULL,NULL);
// if (reg!=ERROR_SUCCESS) MessageBox(0, "Error Opening Registry Key", "Error", 0);
return 0;
}
The comments in the code above where added based on an answer by wmeyer.
When uncommented, the code does not exit with that error, but throws a different error:
Debugging information for Test5.exe
cannot be found or does not match.
Binary was not built with debug
information. Do you want to continue
debugging?
If I continue, the MessageBox pops up with "Error Opening Registry Key".
I have tried replacing the RegQueryValueEx function with the following three other methods, one at a time.
I KNOW THAT TWO OF THEM ARE VISTA ONLY, but I wanted to see if the error would be different.
It wasn't.
long reg = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, hKey);
// Vista+ PHKEY hKey;
long reg = RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", hKey);
long reg = RegGetValue(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "", RRF_RT_ANY, NULL, NULL,NULL);
I've already lost hours trying to work out several other errors, such as "cannot convert parameter 1 from 'char' to 'LPCWSTR'" - which was solved by changing the configuration
and "Cannot find or open the PDB file", solved by changing the configuration.
So again, the question to be clear:
How do I deal with the error?
How did wmeyer's suggestion of adding a header to filter out Vista-only methods help, when the prog has no Vista methods to begin with? And why does the program still not work?
My computer definitely does have a advapi.dll file in Windows/syatem32.
EDIT:
Completely rewrote the question when the answers pointed out how unclear it was.
Originally I had assumed that Visual Studio 2010 is not backwards compatible with XP.
I've been forcefully told that is incorrect, but still can't get VS to work.
If you want your code to run in XP or an earlier system use RegQueryValueEx.
In any case, you should check the documentation first and then search Google. The Win32 API is very well documented, with details on retrieving data from the registry and supported OS information in every function's page, e.g. RegGetValue is supported in XP 64bit and later.
You should set _WIN32_WINNT to the Windows version you are targeting.
See here: http://msdn.microsoft.com/en-us/library/aa383745(v=vs.85).aspx#setting_winver_or__win32_winnt