Embedding Ruby into a Borland C++ Builder Application

Hi Everyone

I’m trying to embed Ruby as the scripting engine into a project of
mine. The project is written in Borland C++ Builder (Codergear Turbo
C++ actually). I searched around for clues on embedding Ruby in C++
Builder but the main link I found was frm 2003 and is this one:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/71319

Is there a more recent guide for this?

I’ve looked at PickAxe 2 and there’s a piece of code there that explains
how to embed Ruby (PickAxe 1 has it here)
http://www.rubycentral.com/pickaxe/ext_ruby.html

This includes “ruby.h” which I found in my distribution at:
ruby\src\ruby-1.8.6 and “ruby.h” starts by including “config.h” which it
can’t find. I can’t find any information on where to provide it from.

I know Windows is less common and Borland C++ Builder even less so, but
a bit of a nudge in the correct direction would help.

Thanks,
Mohit.

Mohit S. wrote:

http://www.rubycentral.com/pickaxe/ext_ruby.html

This includes “ruby.h” which I found in my distribution at:
ruby\src\ruby-1.8.6 and “ruby.h” starts by including “config.h” which it
can’t find. I can’t find any information on where to provide it from.

config.h is system-specific and it should build when you call
win32\configure.bat with your environment set up for the C++ Builder
compiler and tools.

To run it with C++ Builder, you need to build from sources to create a
compatible .lib to link with your project. AFAIK, it’s basically these
steps for any Windows C++ compiler.

  1. Go to a command prompt that has the settings for the compiler and
    make tools
  2. Create a folder where you want your build and go there
  3. Call win32\configure.bat to build config.h and the mak file
  4. Run the make tool
  5. In your C++ project, link with a lib that was created during the make

In theory, that’s what should make it work. Let me know how it works.

Best regards,

Jari W.

Jari W. wrote:

  1. Go to a command prompt that has the settings for the compiler and

Jari W.

Thanks Jari - I didn’t compile from source. I thought I should have
been able to use a pre-compiled version. So, I was using the version
that came with InstantRails. I’ll try out your instructions once I get
back from work today.

Let me also piggy-back new year greetings in this email. Happy new year
everyone!

Cheers,
Mohit.
1/2/2008 | 9:06 AM.

Jari W. wrote:

  1. Create a folder where you want your build and go there
  2. Call win32\configure.bat to build config.h and the mak file
  3. Run the make tool
  4. In your C++ project, link with a lib that was created during the make

In theory, that’s what should make it work. Let me know how it works.

Best regards,

Jari W.

HI Jari

Thanks for the advice and pointing me in the correct direction. The
installed version (in InstantRails) did have a folder for bcc32. Here’s
what I did, starting from that (mostly following the advice in the
Readme there).

[Getting Ruby built on Borland C++ Builder]

  1. From a command window, created a new folder called brb - the
    compiler, linker, etc. was in the path (Your step 1)
  2. Ran bcc32\configure to create some files (incl config.h)
  3. make
  4. This died halfway through because it could not find c0x32.obj though
    it was in the BDS\4.0\lib directory. To make this work, I went to the
    Makefile.sub and updated it to pass the OBJ file path to the ilink32
    executable:
    LD = ilink32 -q -Gn -j"D:\Program Files\Borland\BDS\4.0\lib"
  5. make (this worked now)
  6. make test
  7. make DESTDIR=“E:\rb_bcc” install

After doing all this, I had the config.h that I needed (in the
ruby\src\ruby-1.8.6\brb directory) and the static libs
(bccwin32-ruby18-static.lib, bccwin32-ruby18.lib) in E:\rb_bcc\lib\ and
the DLL (bccwin32-ruby18.dll) in E:\rb_bcc\bin

No idea yet about the performance of Ruby when compiled with Borland
C++.

[Building my application]
For the application, I chose the sample code in ‘Programming Ruby’ that
shows how to embed Ruby in your application.

  1. In Borland C++ Builder, I chose to build a C++ console application.
    When I tried to link and build this, it gave me lots of errors about
    re-definition (some shown below)
    [C++ Error] stdio.h(393): E2167 ‘_strerror(const char *)’ was
    previously declared with the language ‘C’
    [C++ Error] stdio.h(400): E2167 ‘_wperror(const wchar_t *)’ was
    previously declared with the language ‘C’
    [C++ Error] stdio.h(439): E2167 ‘perror(const char *)’ was previously
    declared with the language ‘C’
  2. Then, I created the same thing as a C application and tried to link
    it with the static library. Still no go! I got a few errors for
    undefined references (below):
    [Linker Error] Error: Unresolved external ‘_errno’ referenced from
    E:\RB_BCC\LIB\BCCWIN32-RUBY18-STATIC.LIB|file
    [Linker Error] Error: Unresolved external ‘__doserrno’ referenced from
    E:\RB_BCC\LIB\BCCWIN32-RUBY18-STATIC.LIB|win32
    [Linker Error] Error: Unresolved external ‘WSAEnumProtocolsA’
    referenced from E:\RB_BCC\LIB\BCCWIN32-RUBY18-STATIC.LIB|win32
    [Linker Error] Error: Unresolved external ‘WSASocketA’ referenced from
    E:\RB_BCC\LIB\BCCWIN32-RUBY18-STATIC.LIB|win32
  3. Not sure what to do with it at this stage. I found a reference that
    I had seen earlier
    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/73397
    and tried to create it as a project to link with the DLL. That worked!!

I can now call a simple Ruby script from my C program. Now, I need to
do 3 more things:

  1. Rebuild ruby taking into account some advice about the memory
    manager.
  2. Figure out how to work C++ with Ruby since my current application
    uses all the usual pretty things that Builder offers (and needs C++ for
    it). This may help a bit: http://metaeditor.sourceforge.net/embed/
  3. Figure out how gems work when accessed from embedded Ruby.

I’m sorry that this is a long post but I wanted to jot down all the
stuff I did so that it was available to the next person who may want to
do this. I’m not done yet, but I’d like to put all this down into a
blog post once it all works. But, the above 3 steps stand in the way.

Again, Jari - thanks for getting me started.

Cheers
Mohit.

Hi,

At Thu, 3 Jan 2008 00:31:23 +0900,
Mohit S. wrote in [ruby-talk:285660]:

  1. This died halfway through because it could not find c0x32.obj though
    it was in the BDS\4.0\lib directory. To make this work, I went to the
    Makefile.sub and updated it to pass the OBJ file path to the ilink32
    executable:
    LD = ilink32 -q -Gn -j"D:\Program Files\Borland\BDS\4.0\lib"

It is that your setup wasn’t enough, as you need the option in
general, so put it in ilink32.cfg file.

[Building my application]
For the application, I chose the sample code in ‘Programming Ruby’ that
shows how to embed Ruby in your application.

  1. In Borland C++ Builder, I chose to build a C++ console application.
    When I tried to link and build this, it gave me lots of errors about
    re-definition (some shown below)
    [C++ Error] stdio.h(393): E2167 ‘_strerror(const char *)’ was
    previously declared with the language ‘C’

A simple example of declarations with and without extern “C”
doesn’t err:

extern “C” void foo(void);
void foo(void);

int main(void)
{
foo();
return 0;
}

I haven’t tried to link C++ and am not sure why you failed.

E:\RB_BCC\LIB\BCCWIN32-RUBY18-STATIC.LIB|win32
Seems runtime libraries aren’t linked.

Anyway, bcc version ruby is almost dead now, and may be
deprecated in the future.

Mohit S. wrote:

Based on this, I changes win32.h - it originally has a line like:
#if defined(__cplusplus)
extern “C++” {
#endif
((after this, in does #include for stdio.h, stdlib.h, etc.))

I changed the C++ there to “C” and then it works fine. I also had to
remark out one of the lines in missing.h because it seems that one of
the definitions there is now not missing :slight_smile:

Is there any such thing as extern “C++”? This must be a mistake in the
sources?

Anyway, bcc version ruby is almost dead now, and may be
deprecated in the future.

I hope not! Again, thanks for the tips!

I also hope not. C++Builder (or as the current name, Developer Studio)
is an excellent RAD tool, and for the occasional apps that needs Ruby
scripting it would be great if everything works. A couple of years ago,
I had to use it Ruby in a C++ Builder project, googled about it and
every discussion thread I searched about it ended in a kind of
“uncertain” state. So I finally ended up building a custom DLL wrapper
to the one-click version of the Ruby DLL library instead. Very
time-consuming, since I had to re-prototype every Ruby C function I
needed.

Best regards,

Jari W.

Jari W. wrote:

Mohit S. wrote:

I changed the C++ there to “C” and then it works fine. I also had to
remark out one of the lines in missing.h because it seems that one of
the definitions there is now not missing :slight_smile:

Is there any such thing as extern “C++”? This must be a mistake in the
sources?

I think it’s an error - it’s in win32.h - I found an earlier link that
had stumbled across this as a problem. But, in that person’s case,
changing it back didn’t solve the problem. Anyway, it works for me now.

and every discussion thread I searched about it ended in a kind of
“uncertain” state. So I finally ended up building a custom DLL wrapper
to the one-click version of the Ruby DLL library instead. Very
time-consuming, since I had to re-prototype every Ruby C function I
needed.

I completely agree that Developer Studio does have a lot of good things
and

Best regards,

Jari W.

I’ve started an article to write about the process of embedding Ruby
into Borland C++ Builder which I shall put on my blog at:
http://notepad.onghu.com/2008/1/2/codegear-turbo-c-and-ruby - and will
jot down the notes as I go through the process. I think I’m keen to see
C++ Builder survive and I love Ruby - together, they can do some
fantastic things (rapid development, rapid development!)

Cheers
Mohit.

Hi,

At Thu, 3 Jan 2008 13:49:33 +0900,
Mohit S. wrote in [ruby-talk:285753]:

I changed the C++ there to “C” and then it works fine. I also had to
remark out one of the lines in missing.h because it seems that one of
the definitions there is now not missing :slight_smile:

It must be C++ due to a template without extern “C++”, in
math.h of MSVC6. Microsoft also seems to have considered this
is a problem and fixed it in VC8.

The re-definitions in BCC are caused by C linkage and using std
namespace. Although it also seems quite curious, it should be
fixed as a workaround for VC6.

Hi Nakada-san,

Thank you for your replies. My main reason to use BCC is simply because
we’re using Codegear’s Turbo C++ Professional (Borland C++ Builder) and
would like to embed scripting into our application. I really like
Borland C++ Builder, so I do hope that it doesn’t get deprecated :frowning:

My remaining answers are inline.

Nobuyoshi N. wrote:

  1. This died halfway through because it could not find c0x32.obj though
    it was in the BDS\4.0\lib directory. To make this work, I went to the
    Makefile.sub and updated it to pass the OBJ file path to the ilink32
    executable:
    LD = ilink32 -q -Gn -j"D:\Program Files\Borland\BDS\4.0\lib"

It is that your setup wasn’t enough, as you need the option in
general, so put it in ilink32.cfg file.

I think that’s correct - I need to update ilink32.cfg to include that.

A simple example of declarations with and without extern “C”

I haven’t tried to link C++ and am not sure why you failed.

Linking in a C program works perfectly fine. The problem that I was
having was in a C++ file. I found some hints from another thread:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/215624

Based on this, I changes win32.h - it originally has a line like:
#if defined(__cplusplus)
extern “C++” {
#endif
((after this, in does #include for stdio.h, stdlib.h, etc.))

I changed the C++ there to “C” and then it works fine. I also had to
remark out one of the lines in missing.h because it seems that one of
the definitions there is now not missing :slight_smile:

E:\RB_BCC\LIB\BCCWIN32-RUBY18-STATIC.LIB|win32

Seems runtime libraries aren’t linked.

I think that’s the problem. Anyway, right now, the DLL version works
fine. So, I shall investigate this again.

Anyway, bcc version ruby is almost dead now, and may be
deprecated in the future.

I hope not! Again, thanks for the tips!

Best Regards
Mohit.

Nobuyoshi N. wrote:

changing it back didn’t solve the problem. Anyway, it works for me now.
Maybe, but Borland make is too silly, it should not be named as
`make’.

Haha… I see the point you ‘make’! But, thanks both of you for your
help. I shall put up the instructions for making Ruby 1.8.6 work from
within a C++ Builder application soon. Then, I shall look for the other
items I had on my list (performance and memory management).

Cheers,
Mohit.
1/4/2008 | 12:38 AM.

Hi,

At Fri, 4 Jan 2008 01:06:37 +0900,
Mohit S. wrote in [ruby-talk:285846]:

Is there any such thing as extern “C++”? This must be a mistake in the
sources?

I think it’s an error - it’s in win32.h - I found an earlier link that
had stumbled across this as a problem. But, in that person’s case,
changing it back didn’t solve the problem. Anyway, it works for me now.

It’s valid. The C++ spec requires extern “C” and “C++” at
least. Other linkages e.g., “pascal”, “fortran”, “ada”, etc,
can be implementation defined.

I completely agree that Developer Studio does have a lot of good things and

Maybe, but Borland make is too silly, it should not be named as
`make’.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs