Forum: Ruby How to make compiler independent extension library on Window

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
Park H. (Guest)
on 2006-04-26 19:13
(Received via mailing list)

I know there are some issues with various compiler versions of
ruby distribution and extension library. Mainly VC++6.0 and VC++7.1
conflict. I guess many people have VC++7.1 and want to make extension
library with VC++7.1. The library built with VC++6.0 is not working on
the VC++7.1 compiled ruby distribution and vice versa.

Here is the method to make compiler independent extension library.
Because it is a draft version, some modifications might be needed.

1. Remove compile time dependency on ruby dll(msvcr71-ruby18.dll,
   msvcrt-ruby18.dll or others)

1-1. If not exist ruby_ext.h, make ruby_ext.h with make_header.rb

   ruby make_header.rb

1-2. Insert #include "ruby_ext.h" after the line #include "ruby.h"
      in the library source.

   #include "ruby.h"
   #include "ruby_ext.h"

1-3. Insert get_ruby_function(); at the first place of Init_xxx function
      in the library source.

   void Init_changejournal()
     VALUE mWin32, cChangeJournal;

2. Remove run time dependency on msvcrt dll (msvcrt.dll,msvcr71.dll
   or others) - Optional

  2-1. Insert $CFLAGS.sub!("-MD","-MT") befre create_makefile in the


3. Make extension library as usual

    ruby extconf.rb
    nmake install


Park H.

=====file make_header.rb

require 'rbconfig'['archdir']+'/ruby_ext.h',"w") {|f|
  func_arr = []
  var_arr = []['archdir']+'/ruby.h').each {|l|
    if l =~ /(^.*[\s|\*])(rb_\w*)(\s.+;$)/
      f.puts "typedef #$1 (*p_#$2)#$3";
    elsif l =~ /RUBY_EXTERN VALUE (rb_[c|e]\w*);/
  }['archdir']+'/intern.h').each {|l|
    if l =~ /(^.*\s)(rb_\w*)(\s.+;$)/
      f.puts "typedef #$1 (*p_#$2)#$3";
  func_arr.each {|fn|
    f.puts "#undef #{fn}"
    f.puts "p_#{fn} r_#{fn};"
    f.puts "#define #{fn} r_#{fn}\n"
  var_arr.each {|var|
      f.puts "#undef #{var}"
      f.puts "VALUE r_#{var};"
      f.puts "#define #{var} r_#{var}\n"
  f.puts <<DOC
typedef void *(*p_ruby_xrealloc)(void *ptr, size_t size);
#undef ruby_xrealloc
p_ruby_xrealloc r_ruby_xrealloc;
#define ruby_xrealloc r_ruby_xrealloc

typedef void *(*p_ruby_xmalloc)(size_t size);
#undef ruby_xmalloc
p_ruby_xmalloc r_ruby_xmalloc;
#define ruby_xmalloc r_ruby_xmalloc

  #include <stdio.h>
  #include <stdlib.h>
  HMODULE hinstLib;

  char* get_ruby_dll( void )
     static char   psBuffer[128];
     FILE   *pPipe;

     if( (pPipe = _popen("ruby -r rbconfig -e \\"puts
Config::CONFIG['RUBY_SO_NAME']+'.dll'\\"", "rt" )) == NULL )
        return NULL;

     fgets(psBuffer, 128, pPipe);
     _pclose( pPipe );
     if(*psBuffer) psBuffer[strlen(psBuffer)-1]=0;
     return psBuffer;
  void get_ruby_function()
     hinstLib = LoadLibrary(get_ruby_dll());
     if (hinstLib == NULL)

  func_arr.each {|fn|
    f.puts "#{fn} = (p_#{fn})GetProcAddress(hinstLib, \"#{fn}\");"
  var_arr.each {|var|
    f.puts "#{var} = *(VALUE*)GetProcAddress(hinstLib, \"#{var}\");"
  f.puts "}"
This topic is locked and can not be replied to.