August 09, 2008
Ok, here's the current version I tried:

import std.string;
import std.stdio;
import std.c.windows.windows;

extern (Windows)
alias int function(int,int) setmode_f;

//extern ( C ) int setmode(int,int);

void main(char[][] args)
{
    int O_BINARY = 0x8000;
    setmode_f f;
    HMODULE m = cast(HMODULE) LoadLibraryA(toStringz("msvcrt.dll"));
    f = cast(setmode_f) GetProcAddress(m, toStringz("_setmode"));
    if (f(fileno(stdout), O_BINARY) < 0)
        writefln("setmode failed.");

//    if (setmode(fileno(stdout) ,O_BINARY) < 0)
//        writefln("setmode failed.");
    writef("test line1\r\ntestline2\n");
}

No dice. Still doing CR/LF translation.

Steven Schveighoffer Wrote:

> "Brian Myers" wrote
> > No, I haven't because I thought that would result in a compiler or linker error. What happens is the function is executed at run time, but has no effect. I think I have a better idea now thought:
> 
> Try the extern(Windows).  The difference is the call stack layout.  what could be happening is you are calling a function one way, but the function expects to be called a different way.  So it isn't reading the parameters like you think it is (in fact, it might be reading garbage).
> 
> You won't get a compiler or linker error because you are not linking the function in, you are dynamically loading it.
> 
> -Steve
> 
> 

August 09, 2008
"Brian Myers"
> Ok, here's the current version I tried:
>
> import std.string;
> import std.stdio;
> import std.c.windows.windows;
>
> extern (Windows)
> alias int function(int,int) setmode_f;
>
> //extern ( C ) int setmode(int,int);
>
> void main(char[][] args)
> {
>    int O_BINARY = 0x8000;
>    setmode_f f;
>    HMODULE m = cast(HMODULE) LoadLibraryA(toStringz("msvcrt.dll"));
>    f = cast(setmode_f) GetProcAddress(m, toStringz("_setmode"));
>    if (f(fileno(stdout), O_BINARY) < 0)
>        writefln("setmode failed.");
>
> //    if (setmode(fileno(stdout) ,O_BINARY) < 0)
> //        writefln("setmode failed.");
>    writef("test line1\r\ntestline2\n");
> }
>
> No dice. Still doing CR/LF translation.
>
> Steven Schveighoffer Wrote:
>
>> "Brian Myers" wrote
>> > No, I haven't because I thought that would result in a compiler or
>> > linker
>> > error. What happens is the function is executed at run time, but has no
>> > effect. I think I have a better idea now thought:
>>
>> Try the extern(Windows).  The difference is the call stack layout.  what
>> could be happening is you are calling a function one way, but the
>> function
>> expects to be called a different way.  So it isn't reading the parameters
>> like you think it is (in fact, it might be reading garbage).
>>
>> You won't get a compiler or linker error because you are not linking the function in, you are dynamically loading it.
>>
>> -Steve

I think I see the problem.  dmd is using the digital mars C functions, not the MS C functions.  I think the binary/text translation is done in the C library not in the OS, so setmode will only affect MS C functions. Unfortunately, in looking at Digital Mars' documentation, you cannot reopen an open FILE * object by descriptor only.  I tried using _fdopen, but that isn't available in the lib that ships with dmd.

More proof that it's in the C lib, if you use Tango (which only uses system calls for I/O), setmode also does nothing, but Cout also prints only LF.

-Steve


1 2
Next ›   Last »