Embedded Lua doesn't print to dedicated console

My code looks like this (Windows platform):

AllocConsole();
FILE *fp = freopen("CONOUT$", "w", stdout); //couldn't find documentation what CONOUT$ actually is
lua_State *lua_state = luaL_newstate();
luaL_openlibs(lua_state);
if(luaL_dostring(lua_state, "print 'It works!'"))
{
    printf("%s\n", lua_tostring(lua_state, -1));
}

      

I cannot get Lua output while normal printf is running (Lua errors are also displayed)

0


source to share


2 answers


TL; The DR: . The program uses more than one version of the C runtime library. Don't do this. This always leads to mysterious symptoms from another correct code.

Background

At first glance, your code should work. And, if you build and maintain this, I can make it work. For reference, I am building MingW GCC 4.7.2 for 32-bit Windows on Win7 Pro. But I believe that the main problem can occur with any compiler targeting Windows.

I'm going to go through the process of finding this error, in the hope that it will be helpful to see how I figured it out. But if you're impatient, skip to the end and then come back here to see how I got there.

Controlled code

First, I wrapped the code snippet in enough boiler plates to compile and run:

#include <lua.h>
#include <lauxlib.h>
#include <stdio.h>
#include <windows.h>

int main(int argc, char **argv) {
    AllocConsole();
    FILE *fp = freopen("CONOUT$", "w", stdout); 
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    if(luaL_dostring(L,
             "print 'print works!'\n"
             "io.write 'io.write works'"
            ))
    {
    printf("%s\n", lua_tostring(L, -1));
    }
    Sleep(5000); // give me 5 seconds to read the console
}

      

Compiling with GCC

I compiled and linked as easily as possible with Windows, which is not too bad since I have a copy of Lua for Windows which turns out to leave an environment variable LUA_DEV

pointing to it being installed:

gcc -o q15787892 q15787892.c -mwindows -I"%LUA_DEV%\include" "%LUA_DEV%\lua5.1.dll"

      

The flag -mwindows

tells GCC (specifically the linker ld

) to mark the executable as a complete Windows GUI program. Without this flag, you end up with a console program that already has a console assigned, and AllocConsole () will simply provide descriptors to the one containing the command line.

results



Interestingly, neither the call print()

nor io.write()

output the result. I entered a syntax error in the Lua text and noted that it did output to the console, showing that it was stdout

indeed redirected correctly.

I added FILE *old=stdout;

before freopen()

and printf("%p %p %p", fp, stdout, oldstdout);

after the call . All three pointers were exactly equal, indicating that he freopen()

hadn't done something out of the ordinary.

In the sources for implementing Lua 5.1, print()

we find that it just calls fputs(s,stdout)

.

So how is it possible that a call printf()

from main()

works, but a similar call using use stdout

fails?

Decision

Perhaps, if stdout

in main()

does not match with stdout

in luaB_print()

.

But both are global variables and the linker has to make them the same, right?

Well, not necessarily. The global variable stdout

is part of the C runtime library. If the Lua kernel is linked to a different C runtime library than the program, then it is possible that the Lua kernel and the program actually refer to different named variables stdout

.

A quick check with Dependency Walker reveals that my test executable was linked to MSVCRT.DLL (C runtime preferred by MinGW), but lua5.1.dll

from Lua for Windows it was linked to MSVCR80.DLL (C runtime from Visual Studio 2005).

This problem is easily solved. I modified my test case to link to the Lua assembly linked to MSVCRT.DLL and now the source code works as intended. Here's the new build steps now in the BAT file and assuming it lua5_1-4_Win32_dll6_lib

contains a well-built Lua core:

setlocal
set LUADIR="lua5_1_4_Win32_dll6_lib"
gcc -o q15787892 q15787892.c -mwindows -I"%LUADIR%\include" "%LUADIR%\lua5.1.dll"
if not exist lua5.1.dll copy %LUADIR%\lua5.1.dll .

      

+4


source


Another possible reason is that luaxx.dll is released and the test project is a debug version. In addition, luaxx.dll uses msvcrxx.dll, but the test project uses msvcrxxd.dll - the debug version of the microsoft c environment.



0


source







All Articles