Ruby_run dies w/Borland Builder 5

Answering my own question so the group and anyone Googling in the future
gets the info.

According to the “embedding Ruby” tutorial you need to call ruby_run, but in
fact, at least in Ruby 1.8.0 preview 2, ruby_run always exit()'s, so I
actually needed to call ruby_exec (in order to allow my application to
continue after running the script). No more mysterious crash. Took 2
seconds to find that in the Ruby source. I’m exaggerating, it didn’t take
that long to figure out.

Now the problem I’m having is that print statements are causing the program
to hang. Presumably because the stdio handles Ruby is using aren’t opened
properly because Ruby is being embedded into a true (non-console) Windows
application. I tried using AllocConsole() and freopen() to open up the
handles, and that does allow my application to print just fine, but any
Ruby script code that tries to print simply hangs my application.
Curiously, though, raising an exception, while not printing to stderr as it
should be, also does not cause the application to hang.

Not sure why. I will continue to talk to myself until I figure this out.

Sean O'Dell

“Sean O’Dell” sean@REMOVEME.celsoft.com wrote in message
news:MM4Ga.1997$BG2.1738@newssvr19.news.prodigy.com

Hi,

I got ruby 1.8.0 preview 2 to compile under the bcc32 directory, so I have
what should be Borland C++ 5.0 compatible .dll and import .lib files. I
have written a very simple GUI application in Borland Builder 5.0 (uses
the
Borland C++ 5.5 compiler) which loads ruby, loads a script and then, when
a
button is pressed, calls ruby_run to execute the script. My application
compiles just fine, links to the .dll fine (no errors or messages at all
when compiled and linked) and all calls to the ruby API work fine until I
call ruby_run, when my entire application dies completely and quietly.
See
below for the exact code:

=== RUBY SCRIPT ===

a = 10

=== RUBY SCRIPT ===

=== BORLAND BUILDER CODE ===

VALUE run_protect(VALUE arg)
{
ruby_run();
return 0;
}

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ruby_init();
ruby_script(“billing”);
rb_load_file(“billing.rb”);
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int error;
rb_protect(run_protect, 0, &error);
}

=== BORLAND BUILDER CODE ===

The above code essentially initializes ruby and loads the script when the
application starts. When a button is pressed, ruby_run is called from
inside a rb_protect call. NOTE: the application dies just the same if I
simply call ruby_run from inside the button press (eliminating the
rb_protect wrapper).

One hint might be: when I use the dynamic runtime libraries instead of
static libraries, the application dies with this message: "access
violation

···

at 0x400122c9: write of address 0x00030fc0." This is happening inside the
.dll where I can’t do much debugging, but it might offer a clue.

Sean O'Dell

Hi,

Now the problem I’m having is that print statements are causing the program
to hang. Presumably because the stdio handles Ruby is using aren’t opened
properly because Ruby is being embedded into a true (non-console) Windows
application. I tried using AllocConsole() and freopen() to open up the
handles, and that does allow my application to print just fine, but any
Ruby script code that tries to print simply hangs my application.

You might need to use SetStdHandle() instead of freopen().

Curiously, though, raising an exception, while not printing to stderr as it
should be, also does not cause the application to hang.

What time version are you using? Recent versions stop printing
to $deferr, if an error occurs while exception handling.

···

At Fri, 13 Jun 2003 08:05:39 +0900, Sean O’Dell wrote:


Nobu Nakada

nobu.nokada@softhome.net wrote in message
news:200306130007.h5D07jTS022980@sharui.nakada.kanuma.tochigi.jp…

Hi,

Now the problem I’m having is that print statements are causing the
program
to hang. Presumably because the stdio handles Ruby is using aren’t
opened
properly because Ruby is being embedded into a true (non-console)
Windows
application. I tried using AllocConsole() and freopen() to open up the
handles, and that does allow my application to print just fine, but
any
Ruby script code that tries to print simply hangs my application.

You might need to use SetStdHandle() instead of freopen().

I found the trick to getting the Ruby API to print from a Borland Builder
true Windows application, I think. Basically, “late-load” the bcc32 Ruby
…dll so it doesn’t load until the first Ruby API function is called.
Builder has this option, but I’m not sure about MSVC++. The trick is
two-fold. One, call AllocConsole() any time before your first Ruby call
so the Ruby .dll will automatically load after AllocConsole() is called.
Then simply make the calls shown below before calling any Ruby API function
that might try and print to the console:

dup2(open(“con”, O_RDONLY), 0);
dup2(open(“con”, O_WRONLY), 1);
dup2(open(“con”, O_WRONLY), 2);

Pretty simple.

It also appears from some simple testing I just did, that you can skip the
AllocConsole() call if you open files other than “con” and redirect Ruby’s
output to a file, or perhaps a pipe or socket or what-not.

Sean O'Dell
···

At Fri, 13 Jun 2003 08:05:39 +0900, > Sean O’Dell wrote: