I’m trying to embed ruby 1.9.1 in my Windows application and running
into some problems. I successfully embedded ruby 1.8.4 in the
application, but I’d like to update to use 1.9.1. I’m currently linking
to the .lib and .dll files that I built (using the Microsoft Visual
Studio 2008 compiler) from the ruby 1.9.1 p243 source. I have similar
problems when I link against the 1.9.1 p129 binaries distributed on the
www.ruby-lang.org website.
The root of the problem is that the ruby dll exports a number of
standard library functions that it has redefined. For example, in
include/ruby/win32.h from the source distribution, there are a number of
statements like the following:
#define fclose(f) rb_w32_fclose(f)
I assume this was done so that when ruby calls fclose() on win32
systems, it would more closely match what happens on other systems when
this function is called. Is this a good assumption?
When I build ruby from source (using the instructions found in
win32/README.win32), code in mkexports.rb causes these redefinitions to
be added to the .def file so that they get exported from the dll. This
causes the redefinitions to be viral - anything that links against the
ruby .lib and uses the ruby .dll uses the redefined functions. I assume
this was done with extension writers in mind so that extension code
automatically uses the same redefined std library functions as ruby
itself. However, for embedding ruby, I’m not sure this makes sense. I
don’t mind if ruby does something different with these functions in its
own world, but I don’t want the rest of my application to change simply
because I’m now linking in ruby.
I started looking closely at this issue because my application was
crashing when the redefined fclose() was called. It turns out that the
redefined function calls _get_osfhandle(), and that function doesn’t
like the passed in parameter. Thus, the invalid parameter handler gets
called, which, by default, exits the program. One thing that made me
suspicious was that fclose() was redefined for my platform, but fopen()
wasn’t.
I got around this issue by commenting out the code in mkexports.rb that
adds these redefinitions to the .def file. This means that the library
functions are still redefined within the ruby dll, but NOT for
applications that link to the .lib. After building ruby and linking it
in with my application, all seems to work out ok. However, I’m reluctant
to implement this as a final solution, because I’d prefer not to ship a
non-standard ruby dll with my application.
In summary, here are my questions:
-
Is it correct to assume that std library functions have been
redefined for win32 ruby to maintain consistency within ruby across
platforms? -
Are these redefined std library functions exported from the .dll to
ensure extensions use the same code as ruby itself? If so, doesn’t this
cause problems for applications that embed ruby? -
If it’s really necessary to redefine fclose(), why isn’t fopen()
redefined symmetrically. -
Am I missing some configuration setting somewhere that will prevent
these redefined functions from being exported from the dll? -
Is my method of commenting out code to eliminate these exports sound?
Thanks for your help.
Chris Tenbrink