ruby_run dies w/Borland Builder 5 
Author Message
 ruby_run dies w/Borland Builder 5

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;

Quote:
}

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

Quote:
}

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

Quote:
}

=== 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



Tue, 29 Nov 2005 03:46:52 GMT  
 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


Quote:
> 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



Tue, 29 Nov 2005 06:57:44 GMT  
 ruby_run dies w/Borland Builder 5
Hi,

At Fri, 13 Jun 2003 08:05:39 +0900,

Quote:

> 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().

Quote:
> 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.

--
Nobu Nakada



Tue, 29 Nov 2005 08:07:47 GMT  
 ruby_run dies w/Borland Builder 5

Quote:
> Hi,

> At Fri, 13 Jun 2003 08:05:39 +0900,

> > 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



Tue, 29 Nov 2005 13:03:44 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Borland C++ Builder vs CW

2. Borland C++ Builder is comming to Dallas

3. LabVIEW6 as Automation Server in Borland C++ Builder

4. LabVIEW6 as Automation Server in Borland C++ Builder

5. How to use Cecil under Borland C++ Builder?

6. Embedding in Borland C++ Builder

7. Scheme Package for Borland C++ Builder

8. Inline ASM and Borland C++Builder 5.5

9. Need HELP with Tasm in Borland C++ Builder Professional

10. Borland C++ Builder is comming to Dallas

11. Embedding Python in Borland C++ Builder 5.x?

 

 
Powered by phpBB® Forum Software