Ask a Question related to Ruby, Design and Development.
-
thierry wilmot #1
stdout in embedded ruby in win32
I have just finished to convert my ruby embedded app from static ruby
lib (msvcrt-ruby18-static.lib) to dll, and have some problems with
standard stream stdin,stdout,stderr redirection in dll mode. My .exe is
not compile in console mode, but in windows mode.
a well works code in static lib :
freopen("stdout.txt","w+",stdout);
Does not work in dll mode, cause some unobvious Windows reasons a dll
have it own std streams, and if your freopen() streams in .exe, they
will not be redirected in the msvcrt-ruby18.dll
redisrected $stdout, $stderr in ruby code is not enough. I need to catch
all backtrace when exceptions occurs.
any ideas ?
thierry wilmot Guest
-
How to create or modify an Excel file with embedded charts w/o Win32::OLE?
I am creating a web application that creates custom excel workbooks containing embedded charts for users to download. I know Win32::OLE can do... -
Redirect stdout, stderr to file and stdout
I have a small script that does some admin work for me. What I need to do now is not only have is display information to STDERR and STDOUT but... -
Embedded Ruby in a MSVC++ project?
Hey all, I'm working on a project in MS Visual C++, unfortunately the code is completely tied to that environment and that IDE so I'm trapped. ... -
[BUG?] UTF8 ruby and win32 dir
Does it help if you run with -K? (aka $-K) Dan -
Ruby on an embedded ARM processor
On Sat, Jul 12, 2003 at 09:53:27AM +0900, Ben Giddings wrote: Since you're developing in C, presumably you have a cross-compiler? Why not just... -
Simon Strandgaard #2
Re: stdout in embedded ruby in win32
On Thu, 11 Sep 2003 00:13:34 +0200, thierry wilmot wrote:
I once attempted to redirect *all* output from Ruby, but it was on unix.> I have just finished to convert my ruby embedded app from static ruby
> lib (msvcrt-ruby18-static.lib) to dll, and have some problems with
> standard stream stdin,stdout,stderr redirection in dll mode. My .exe is
> not compile in console mode, but in windows mode.
>
> a well works code in static lib :
>
> freopen("stdout.txt","w+",stdout);
>
> Does not work in dll mode, cause some unobvious Windows reasons a dll
> have it own std streams, and if your freopen() streams in .exe, they
> will not be redirected in the msvcrt-ruby18.dll
>
> redisrected $stdout, $stderr in ruby code is not enough. I need to catch
> all backtrace when exceptions occurs.
>
> any ideas ?
Things works different on windows. Later $defout and $deferr got added.
Reading your post, it seem like you already have managed to redirect
$stdout and $stderr ? Is this correct ?
If so then you just have to redirect $defout and $deferr, and that should
be it (I guess).
--
Simon Strandgaard
Simon Strandgaard Guest
-
Zane Dodson #3
Re: stdout in embedded ruby in win32
On Thu, Sep 11, 2003 at 06:09:58AM +0900, thierry wilmot wrote:
| a well works code in static lib :
|
| freopen("stdout.txt","w+",stdout);
|
| Does not work in dll mode, cause some unobvious Windows reasons a dll
| have it own std streams, and if your freopen() streams in .exe, they
| will not be redirected in the msvcrt-ruby18.dll
Hello Thierry,
In my experience, the results you describe above occur when you mix
different C/C++ runtime libraries (which is far too easy to do
accidently IMO).
Take a look at
[url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdkintro/sdkintro/mixing_library_types.asp[/url]
Best regards,
--
Zane Dodson
[email]zdodson@zdodson.com[/email]
Zane Dodson Guest
-
nobu.nokada@softhome.net #4
Re: stdout in embedded ruby in win32
Hi,
At Thu, 11 Sep 2003 06:09:58 +0900,
thierry wilmot wrote:Link with msvcrt.dll.> I have just finished to convert my ruby embedded app from static ruby
> lib (msvcrt-ruby18-static.lib) to dll, and have some problems with
> standard stream stdin,stdout,stderr redirection in dll mode. My .exe is
> not compile in console mode, but in windows mode.
Due to the specification of Windows DLL. And if you want to> a well works code in static lib :
>
> freopen("stdout.txt","w+",stdout);
>
> Does not work in dll mode, cause some unobvious Windows reasons a dll
> have it own std streams, and if your freopen() streams in .exe, they
> will not be redirected in the msvcrt-ruby18.dll
use extension libraries, you have to use ruby DLL or recompile
all libraries to import symbols from your .exe.
--
Nobu Nakada
nobu.nokada@softhome.net Guest
-
Sean O'Dell #5
Re: stdout in embedded ruby in win32
[email]nobu.nokada@softhome.net[/email] wrote:
Not sure if this solves your problem Thierry, but here's what I did in> Hi,
>
> At Thu, 11 Sep 2003 06:09:58 +0900,
> thierry wilmot wrote:
>>>>I have just finished to convert my ruby embedded app from static ruby
>>lib (msvcrt-ruby18-static.lib) to dll, and have some problems with
>>standard stream stdin,stdout,stderr redirection in dll mode. My .exe is
>>not compile in console mode, but in windows mode.
>
> Link with msvcrt.dll.
>
>>>>a well works code in static lib :
>>
>> freopen("stdout.txt","w+",stdout);
>>
>>Does not work in dll mode, cause some unobvious Windows reasons a dll
>>have it own std streams, and if your freopen() streams in .exe, they
>>will not be redirected in the msvcrt-ruby18.dll
>
> Due to the specification of Windows DLL. And if you want to
> use extension libraries, you have to use ruby DLL or recompile
> all libraries to import symbols from your .exe.
my Windows application to "capture" stdio streams used by the Ruby DLL:
First, in the Ruby .dll, I hacked in these functions:
int rb_w32_redirect_stdin(HANDLE pipe)
{
return dup2(_open_osfhandle((long)pipe, _O_TEXT), 0);
}
int rb_w32_redirect_stdout(HANDLE pipe)
{
return dup2(_open_osfhandle((long)pipe, _O_TEXT), 1);
}
int rb_w32_redirect_stderr(HANDLE pipe)
{
return dup2(_open_osfhandle((long)pipe, _O_TEXT), 2);
}
.... and exported them. Then in my application, I call:
// thread that continually grabs Ruby's stdout output
unsigned long __stdcall stdioReadThread(void* parameter)
{
DWORD dwRead;
char chBuf[READ_THREAD_BUFFER_SIZE];
for( ;; )
{
if(!ReadFile(stdioReadHandle, chBuf, READ_THREAD_BUFFER_SIZE - 1,
&dwRead, NULL) || dwRead == 0)
break;
chBuf[dwRead / sizeof(char)] = '\0';
// DO SOMETHING WITH THE BUFFER HERE
}
return 0;
}
// create pipe that replaces Ruby's stdout
if(CreatePipe(&stdioReadHandle, &stdioWriteHandle, NULL, 0))
{
dup2(_open_osfhandle((long)stdioWriteHandle, _O_TEXT), 1);
dup2(_open_osfhandle((long)stdioWriteHandle, _O_TEXT), 2);
stdioReadThreadHandle = CreateThread(NULL, 0, stdioReadThread,
outputTextBox, 0, &stdioReadThreadID);
}
// then call init, and re-assign Ruby's stdout handle
ruby_init();
rb_w32_redirect_stdout(GetStdHandle(STD_OUTPUT_HAN DLE));
The read thread will basically "sleep" on the pipe until Ruby sends
output to the stdout handle. When it wakes up, it starts pulling from
the pipe. The example above basically does nothing, but in my
application, I sent the output to a textbox to simulate an output
console. You could modify the read thread to do whatever you want with
the output.
Hope that helps ... someone ...
Sean O'Dell
Sean O'Dell Guest
-
thierry wilmot #6
Re: stdout in embedded ruby in win32
First , thanks all for your answers, ruby community is great !
Simon Strandgaard : I try to redicrect $defout, $deferr, it no works
better and Ruby interpetor tell me these variables will now be obslete.
Zane Dodson : Ok, I think I have here a beginning of answer. I compile
my app in debug mode and link it with msvcrt-ruby18.dll compiled in
release mode. Dependency walker show me that my app mount msvcrtd.dll
and msvcrt.dll for ruby's dll. I try to compile ruby in debug mode, and
all seems to work fine. (I not find an easy way to compile ruby dll in
debug, so I hack makefile.sub)
Nobu Nakada : Yes, when using Ruby static lib you can call all core ruby
functions in a more easiest way than in dll mode, but if you wanna use
extensions like webrick or drd, you must first found dll/so used by
there extensions and link them to your app. That a never ending story !
Sean O'Dell wrote:> [email]nobu.nokada@softhome.net[/email] wrote:
>>>> Hi,
>>
>> At Thu, 11 Sep 2003 06:09:58 +0900,
>> thierry wilmot wrote:
>>>>>>> I have just finished to convert my ruby embedded app from static ruby
>>> lib (msvcrt-ruby18-static.lib) to dll, and have some problems with
>>> standard stream stdin,stdout,stderr redirection in dll mode. My .exe
>>> is not compile in console mode, but in windows mode.
>>
>>
>> Link with msvcrt.dll.
>>
>>>>>>> a well works code in static lib :
>>>
>>> freopen("stdout.txt","w+",stdout);
>>>
>>> Does not work in dll mode, cause some unobvious Windows reasons a dll
>>> have it own std streams, and if your freopen() streams in .exe, they
>>> will not be redirected in the msvcrt-ruby18.dll
>>
>>
>> Due to the specification of Windows DLL. And if you want to
>> use extension libraries, you have to use ruby DLL or recompile
>> all libraries to import symbols from your .exe.
>
> Not sure if this solves your problem Thierry, but here's what I did in
> my Windows application to "capture" stdio streams used by the Ruby DLL:
>
>
>
> First, in the Ruby .dll, I hacked in these functions:
>
>
>
> int rb_w32_redirect_stdin(HANDLE pipe)
> {
> return dup2(_open_osfhandle((long)pipe, _O_TEXT), 0);
> }
>
> int rb_w32_redirect_stdout(HANDLE pipe)
> {
> return dup2(_open_osfhandle((long)pipe, _O_TEXT), 1);
> }
>
> int rb_w32_redirect_stderr(HANDLE pipe)
> {
> return dup2(_open_osfhandle((long)pipe, _O_TEXT), 2);
> }
>
>
>
> ... and exported them. Then in my application, I call:
>
>
>
> // thread that continually grabs Ruby's stdout output
> unsigned long __stdcall stdioReadThread(void* parameter)
> {
> DWORD dwRead;
> char chBuf[READ_THREAD_BUFFER_SIZE];
>
> for( ;; )
> {
> if(!ReadFile(stdioReadHandle, chBuf, READ_THREAD_BUFFER_SIZE - 1,
> &dwRead, NULL) || dwRead == 0)
> break;
> chBuf[dwRead / sizeof(char)] = '\0';
> // DO SOMETHING WITH THE BUFFER HERE
> }
>
> return 0;
> }
>
>
>
> // create pipe that replaces Ruby's stdout
> if(CreatePipe(&stdioReadHandle, &stdioWriteHandle, NULL, 0))
> {
> dup2(_open_osfhandle((long)stdioWriteHandle, _O_TEXT), 1);
> dup2(_open_osfhandle((long)stdioWriteHandle, _O_TEXT), 2);
>
> stdioReadThreadHandle = CreateThread(NULL, 0, stdioReadThread,
> outputTextBox, 0, &stdioReadThreadID);
> }
>
>
>
> // then call init, and re-assign Ruby's stdout handle
> ruby_init();
> rb_w32_redirect_stdout(GetStdHandle(STD_OUTPUT_HAN DLE));
>
>
>
> The read thread will basically "sleep" on the pipe until Ruby sends
> output to the stdout handle. When it wakes up, it starts pulling from
> the pipe. The example above basically does nothing, but in my
> application, I sent the output to a textbox to simulate an output
> console. You could modify the read thread to do whatever you want with
> the output.
>
> Hope that helps ... someone ...
>
> Sean O'Dell
>thierry wilmot Guest
-
Zane Dodson #7
Re: stdout in embedded ruby in win32
On Fri, Sep 12, 2003 at 04:33:44AM +0900, thierry wilmot wrote:
| First , thanks all for your answers, ruby community is great !
|
|<snip>
|
| Zane Dodson : Ok, I think I have here a beginning of answer. I compile
| my app in debug mode and link it with msvcrt-ruby18.dll compiled in
| release mode. Dependency walker show me that my app mount msvcrtd.dll
| and msvcrt.dll for ruby's dll. I try to compile ruby in debug mode, and
| all seems to work fine. (I not find an easy way to compile ruby dll in
| debug, so I hack makefile.sub)
|
| <snip>
What you state above is consistent with my experience. You need
everything linked with the same runtime DLL. This means the
executable and all dependent DLLs. As I understand it, Microsoft
has provided 3 different libraries, each in 2 varieties (debug and
non-debug), providing 6 different ways to link the C runtime with an
executable or DLL. If an executable or any of its dependent DLLs is
linked with more than one of these runtime libraries, disaster is
generally the result.
Here is another link you might find helpful on this very confusing
topic.
[url]http://support.microsoft.com/default.aspx?scid=kb;en-us;94248[/url]
Best regards,
--
Zane Dodson
[email]zdodson@zdodson.com[/email]
Zane Dodson Guest



Reply With Quote

