# How to make compiler independent extension library on Window

**URL:** <https://www.ruby-forum.com/t/how-to-make-compiler-independent-extension-library-on-window/58860>\
**Category:** Ruby\
**Created:** [April 26, 2006, 5:13pm UTC](https://www.ruby-forum.com/t/how-to-make-compiler-independent-extension-library-on-window/58860 "2006-04-26T17:13:36Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Park\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/a4c791/32.png) [@Park\_H](https://www.ruby-forum.com/u/Park_H)\
**Post date:** [April 26, 2006, 5:13pm UTC](https://www.ruby-forum.com/t/how-to-make-compiler-independent-extension-library-on-window/58860/1 "2006-04-26T17:13:36Z")

</div>

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

1. 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")

```

1. Make extension library as usual

Regards,

Park H.

=====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 “}”  
}
