Hello,
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;
get_ruby_function();
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 extconf.rb
$CFLAGS.sub!("-MD","-MT")
create_makefile("win32/changejournal")
3. Make extension library as usual
ruby extconf.rb
nmake install
Regards,
Park Heesob
=====file make_header.rb
require 'rbconfig'
File.open(Config::CONFIG['archdir']+'/ruby_ext.h',"w") {|f|
func_arr = []
var_arr = []
File.read(Config::CONFIG['archdir']+'/ruby.h').each {|l|
if l =~ /(^.*[\s|\*])(rb_\w*)(\s.+;$)/
f.puts "typedef #$1 (*p_#$2)#$3";
func_arr.push($2);
elsif l =~ /RUBY_EXTERN VALUE (rb_[c|e]\w*);/
var_arr.push($1)
end
}
File.read(Config::CONFIG['archdir']+'/intern.h').each {|l|
if l =~ /(^.*\s)(rb_\w*)(\s.+;$)/
f.puts "typedef #$1 (*p_#$2)#$3";
func_arr.push($2);
end
}
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)
{
exit(1);
}
DOC
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 "}"
}