| Thread overview | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 07, 2008 setmode again | ||||
|---|---|---|---|---|
| ||||
Hi all,
Seems this gets revisited every so often on the forums, so I guess it's time to visit it again...
I need to set stdout to binary mode in Windows. I've tried the following:
import std.string;
import std.stdio;
import std.c.windows.windows;
extern (C)
alias int function(int,int) setmode_f;
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"));
f(fileno(stdout), O_BINARY);
writef("test line1\r\ntestline2");
}
and
import std.string;
import std.stdio;
extern (C)
alias int function(int,int) setmode_f;
extern ( C ) int setmode(int,int);
void main(char[][] args)
{
int O_BINARY = 0x8000;
if (setmode(fileno(stdout) ,O_BINARY) < 0)
writefln("setmode failed.");
writef("test line1\r\ntest line2");
}
No luck. Both compile and run without error, but Windows is still doing LF->CRLF translation.
I know I need a version statement for a cross platform compile, but this is just example code.
Brian
| ||||
August 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian Myers | Ugh, By the rush to respond I'm getting so far, I'm guessing nobody does these kind of programs these days. Can't say I'm surprised, but I'm stuck working with legacy data. Anyway, for everyone's reference, the following python code works perfectly: import os, msvcrt import sys msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) print "test line1\r\ntestline2" Brian Myers Wrote: > Hi all, > > Seems this gets revisited every so often on the forums, so I guess it's time to visit it again... > > I need to set stdout to binary mode in Windows. I've tried the following: > > import std.string; > import std.stdio; > import std.c.windows.windows; > > extern (C) > alias int function(int,int) setmode_f; > > 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")); > f(fileno(stdout), O_BINARY); > > writef("test line1\r\ntestline2"); > } > > and > > import std.string; > import std.stdio; > > extern (C) > alias int function(int,int) setmode_f; > > extern ( C ) int setmode(int,int); > > void main(char[][] args) > { > int O_BINARY = 0x8000; > > if (setmode(fileno(stdout) ,O_BINARY) < 0) > writefln("setmode failed."); > writef("test line1\r\ntest line2"); > } > > No luck. Both compile and run without error, but Windows is still doing LF->CRLF translation. > > I know I need a version statement for a cross platform compile, but this is just example code. > > Brian > | |||
August 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian Myers |
"Brian Myers" wrote
> Ugh,
>
> By the rush to respond I'm getting so far, I'm guessing nobody does these kind of programs these days. Can't say I'm surprised, but I'm stuck working with legacy data.
>
> Anyway, for everyone's reference, the following python code works perfectly:
>
> import os, msvcrt
> import sys
>
> msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
> print "test line1\r\ntestline2"
>
> Brian Myers Wrote:
>
>> Hi all,
>>
>> Seems this gets revisited every so often on the forums, so I guess it's time to visit it again...
>>
>> I need to set stdout to binary mode in Windows. I've tried the following:
>>
>> import std.string;
>> import std.stdio;
>> import std.c.windows.windows;
>>
>> extern (C)
>> alias int function(int,int) setmode_f;
>>
>> 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"));
>> f(fileno(stdout), O_BINARY);
>>
>> writef("test line1\r\ntestline2");
>> }
>>
>> and
>>
>> import std.string;
>> import std.stdio;
>>
>> extern (C)
>> alias int function(int,int) setmode_f;
>>
>> extern ( C ) int setmode(int,int);
>>
>> void main(char[][] args)
>> {
>> int O_BINARY = 0x8000;
>>
>> if (setmode(fileno(stdout) ,O_BINARY) < 0)
>> writefln("setmode failed.");
>> writef("test line1\r\ntest line2");
>> }
>>
>> No luck. Both compile and run without error, but Windows is still doing LF->CRLF translation.
>>
>> I know I need a version statement for a cross platform compile, but this is just example code.
>>
>> Brian
>>
>
Have you tried changing extern(C) to extern(Windows)?
-Steve
| |||
August 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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: Check out this C code: #include <fcntl.h> #include <io.h> #include <string.h> #include <stdio.h> void main() { char *tmp = "Test line1\r\ntest line2\n"; _setmode(_fileno(stdout), _O_BINARY); fwrite(tmp, strlen(tmp), sizeof(char), stdout); } When compiled and linked with MSVC, it works properly. When compiled with DMC, it doesn't. Could there be something wrong with the DMC CRT? I would suspect the D runtime library is built on the same code, and that's why it's not working properly. OTOH, then why didn't it work properly when I loaded the _setmode function out of MSVCRT directly? I'm sure that's what the python code is doing. Well, pretty sure anyway. Errrrgh! This is one of the many reasons I hate M$. Steven Schveighoffer Wrote: > > "Brian Myers" wrote > > Ugh, > > > > By the rush to respond I'm getting so far, I'm guessing nobody does these kind of programs these days. Can't say I'm surprised, but I'm stuck working with legacy data. > > > > Anyway, for everyone's reference, the following python code works perfectly: > > > > import os, msvcrt > > import sys > > > > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) > > print "test line1\r\ntestline2" > > > > Brian Myers Wrote: > > > >> Hi all, > >> > >> Seems this gets revisited every so often on the forums, so I guess it's time to visit it again... > >> > >> I need to set stdout to binary mode in Windows. I've tried the following: > >> > >> import std.string; > >> import std.stdio; > >> import std.c.windows.windows; > >> > >> extern (C) > >> alias int function(int,int) setmode_f; > >> > >> 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")); > >> f(fileno(stdout), O_BINARY); > >> > >> writef("test line1\r\ntestline2"); > >> } > >> > >> and > >> > >> import std.string; > >> import std.stdio; > >> > >> extern (C) > >> alias int function(int,int) setmode_f; > >> > >> extern ( C ) int setmode(int,int); > >> > >> void main(char[][] args) > >> { > >> int O_BINARY = 0x8000; > >> > >> if (setmode(fileno(stdout) ,O_BINARY) < 0) > >> writefln("setmode failed."); > >> writef("test line1\r\ntest line2"); > >> } > >> > >> No luck. Both compile and run without error, but Windows is still doing LF->CRLF translation. > >> > >> I know I need a version statement for a cross platform compile, but this is just example code. > >> > >> Brian > >> > > > > Have you tried changing extern(C) to extern(Windows)? > > -Steve > > | |||
August 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian Myers | You can always build it into a VS DLL then link it into D | |||
August 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian Myers | 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:
>
> Check out this C code:
>
> #include <fcntl.h> #include <io.h> #include <string.h> #include
> <stdio.h>
>
> void main() { char *tmp = "Test line1\r\ntest line2\n"; _setmode(_fileno(stdout), _O_BINARY); fwrite(tmp, strlen(tmp),
> sizeof(char), stdout); }
>
> When compiled and linked with MSVC, it works properly. When compiled
> with DMC, it doesn't. Could there be something wrong with the DMC
> CRT? I would suspect the D runtime library is built on the same code,
> and that's why it's not working properly.
Try:
stdout->_flag &= ~_IOTRAN;
in the C code.
| |||
August 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Wyverex | I could and probably will, but the fact that it's a problem remains. I don't like having to depend on the M$ compiler to build my D language projects, and I don't like having to distribute a DLL with them. I prefer all of the programs to be standalone executables.
Does Walter have a bugzilla for the C/C++ forum?
Wyverex Wrote:
>
> You can always build it into a VS DLL then link it into D
| |||
August 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian Myers | "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 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Hi Walter, The following code compiled with DMC still doesn't work: #include <fcntl.h> #include <io.h> #include <string.h> #include <stdio.h> void main() { char *tmp = "Test line1\r\ntest line2\n"; //_setmode(_fileno(stdout), _O_BINARY); stdout->_flag &= ~_IOTRAN; fwrite(tmp, strlen(tmp), sizeof(char), stdout); } Want me to try anything else? Walter Bright 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: > > > > Check out this C code: > > > > #include <fcntl.h> #include <io.h> #include <string.h> #include <stdio.h> > > > > void main() { char *tmp = "Test line1\r\ntest line2\n"; > > _setmode(_fileno(stdout), _O_BINARY); fwrite(tmp, strlen(tmp), > > sizeof(char), stdout); } > > > > When compiled and linked with MSVC, it works properly. When compiled with DMC, it doesn't. Could there be something wrong with the DMC CRT? I would suspect the D runtime library is built on the same code, and that's why it's not working properly. > > Try: > stdout->_flag &= ~_IOTRAN; > in the C code. | |||
August 08, 2008 Re: setmode again | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian Myers | Brian Myers wrote: > Does Walter have a bugzilla for the C/C++ forum? http://bugzilla.digitalmars.com/issues/buglist.cgi?quicksearch=. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply