3

I have read and tried many solutions and nothing solved my problem.

I am generating a dll out of c++ code and want to display the printf() or the std::cout inside of a console window. For testing I just create a .exe out of the c++ code but that is not solving the problem!

I know that system("Pause") is a bad habit, but this is just an easy way to get the same problem. Instead of calling system("Pause") I'm doing a system()-call that is calling the cl.exe and is compiling a dll out of a .c file(Like: system("cl...). The generation of the dll out of the other c file is working without any problems. But after I called the system function for compiling the dll file the printf and std::out are not displaying the right text in the console window.

here is my example code that is screwing up the display of the right characters:

#include "stdafx.h"
#include <iostream>
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    AllocConsole();
    freopen("CONOUT$", "w", stdout); 
    std::cout << "Everything works fine\n";
    // Calling the cl.exe by cmd...
    system("Pause");
    std::cout << "now its strewd up the newline is not working\n" << std::endl;
    FreeConsole();
    return 0;
}

Here is a picture of the output:

Output of the std::cout

I tried the fflush before and after calling the system().

So here are my further thoughts:

  • Could I call the cl.exe by a CreateProcess and would that solve my problem?And when yes, how will I do that and to implement the environment variables out of the batch vcvars32.bat. So I want to create a dll out of a .c located both in the same folder.
  • Or could write a batch file that is calling the whole cl.exe and vcvars32.bat file process.
  • Or is there another way to display the values out of a dll instead of calling AllocConsole()?

I hope you can help me maybe I'm missing something!

Carey Gregory
  • 6,836
  • 2
  • 26
  • 47
Noxious
  • 87
  • 8
  • 1
    removing `freopen("CONOUT$", "w", stdout);` gives the correct output. – NathanOliver Oct 02 '15 at 14:42
  • But it will not display then the std::cout inside of the dll right? Because I just did AllocConsole() and calling afterwards a std::cout isn't displaying anything. The freopen is for refering the stdout to the allocated console? – Noxious Oct 02 '15 at 14:47
  • I have no idea what you're trying to accomplish with `AllocConsole` and `freopen`, but it works perfectly fine without them. Why would you expect they're needed? – Carey Gregory Oct 02 '15 at 14:50
  • As I have written in the question, normally that code is not inside of a .exe solution. This code is generated as a dll and will be called from a c# project. But the thing is I want to get the same display when calling the c++.dll inside of a command window. And because of the non existing command window by a dll I read about that AllocConsole is opening a command window even inside of a dll and freopen is linking the stdout stream to the command window. – Noxious Oct 02 '15 at 14:56
  • 1
    Okay, if I understand correctly, you want to have a `DLL` that will be called from an `EXE` that has no console window, but you want your `DLL` to have a visible console window so you can see its output. And you want to do this without using `cmd.exe`. Is that correct? – Carey Gregory Oct 02 '15 at 15:09
  • I'm calling that dll out of a c# project but the rest is the right thing I want to do. I thought I just could use the Std::out function of c++ inside of the dll and that is working well until I'm calling the cl.exe inside of a system() call after that the displaying of the following Std::cout calls are not displayed in the right line so they are not insert into a newline by \n or Std::endl. – Noxious Oct 02 '15 at 15:34
  • Every time I think I understand your question you start talking about cl.exe and `system()`. What do they have to do with creating a DLL that shows its output in a console window? I simply don't understand what you're trying to do. – Carey Gregory Oct 02 '15 at 19:00
  • @CareyGregory: seems clear enough. The DLL needs to show output in a console window, and it also needs to run `cl.exe` as a child process. The latter, for some reason, messes up the former. – Harry Johnston Oct 03 '15 at 00:25
  • I suspect the problem relates to the C runtime. Have you tried using CreateFile and WriteFile instead of freopen and std::cout? – Harry Johnston Oct 03 '15 at 00:27
  • @Harry Johnston: you mean to try writing in a file instead of displaying it?or can I use CreateFile and WriteFile for also displaying the std::cout into a command window? – Noxious Oct 03 '15 at 08:05
  • Re your title "Screwing up `\n\r\t` by system()": `\n\r` is not a valid line terminator on any computer system known to man. Counter-examples welcomed. The known line terminators are: - `\n` (Unix) -`\r` (Windows) - `\r\n` (most other systems dating back to the ASR-33) See [here](http://stackoverflow.com/questions/3307747/difference-between-newline-and-carriage-return-r/3315133?s=1|0.8255#3315133) for why. Re your question, unclear what it has to do with your title. – user207421 Oct 03 '15 at 09:57
  • @EJP I know that this order is incorrect! But this is just because any of this terminators is screwed up, so there is no reason to say this question titel is unclear.it's no order it's just a listing of terminators that I now which are not displayed right. – Noxious Oct 03 '15 at 10:12
  • @Noxious: yes, you can use CreateFile and WriteFile to write to a console window, using the `CONOUT$` device name. – Harry Johnston Oct 03 '15 at 12:37

2 Answers2

1

So in order to try these error on my laptop (because I'm travelling today) I set up the same code at my laptop. Because I forgot to uncheck Security Development Lifecycle (SDL) checks there was an error when calling freopen("CONOUT$", "w", stdout); .Because the error message at building the code inside of visual studio 2015 was:

Severity Code Description Project File Line Error C4996 'freopen': This function or variable may be unsafe. Consider using freopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ConsoleApplication1 c:\users\noxious\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp 12

I searched for the function freopen_s and exact at a example of freopen_s I saw the following code Outputting Unicode to Allocated Console Issue:

freopen_s(&stream, "CONOUT$", "w+t", stdout);

I tried this one and acually my problem was solved! BUT it wasn't the freopen_s that solved the problem it was just the inside of it "w+t" so I looked it up and saw that w+ is refering to the following type of access cstdio: freopen:

"w+" Create an empty file for reading and writing. If a file with the same name already exists its content is erased before it is opened.

So I tried a few combinations and got this resulst:

  • wt not working
  • w+t working (but the t is always standard even if you use w+ is the same as w+t
  • w+ working

So I think I have just to setup an empty file for reading and writing! I will looking further deep into that because I'm not quite sure what is the difference and if it is still solving the problem when using the dll instead of the exe file! Hope this might help some other people who are trying to solve same errors! But just a "+" was delaying my work now for more than one day!

Edit 5.10.2015: So I tested this function with the "w+" instead of "w" and it fixed my problem!Even using a dll instead of a generated exe!

Noxious
  • 87
  • 8
0

It looks like the process is changing the output codepage on the console, then not changing it back when it's done. Not sure why this would happen, but if that's the cause, it should be sufficient to save and restore the codepage:

AllocConsole();
freopen("CONOUT$", "w", stdout); 
std::cout << "Everything works fine\n";
// Calling the cl.exe by cmd...
UINT codepage = GetConsoleOutputCP();
system("Pause");
SetConsoleOutputCP(codepage);
std::cout << "Should work now." << std::endl;
FreeConsole();
return 0;

BTW, it might also be screwing up the input codepage. You can use GetConsoleCP() and SetConsoleCP() for that.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • Surely the code page does not influence the internal (!) processing of ᴄʀ and ʟғ? – Jongware Oct 02 '15 at 14:41
  • 1
    I tested this and it does not fix the output – NathanOliver Oct 02 '15 at 14:42
  • What I was thinking if there is something strewed up inside of how the std::cout is converting the \n to the newline. I thought I have learned something about it years ago in IT class but still couldn't remember what it was. Is there a way to check the conversion is working in the same way as it previously worked? – Noxious Oct 02 '15 at 14:42
  • 1
    The code page is correct, those characters correspond to [code page 437](https://en.wikipedia.org/wiki/Code_page_437) representations of 0x0d and 0x0a. There must be some kind of mode on the console window that tells it whether to interpret the characters or display them. – Mark Ransom Oct 02 '15 at 15:12
  • I had the same idea but could find out where this will happen. But this is the problem I think. Another point is maybe I'm calling the cmd to execute the cl.exe bad implementation I know but maybe you can tell me how to do the same cl call with a createProcess and this will solve the problem. In createProcess I'm not quite sure how I should set the environmental variables for the vs 2010 Compiler. I just know that there is a batchfile that is creating this environment when executed before calling the cl.exe inside of a cmd. – Noxious Oct 02 '15 at 16:20