One Way to Write VCRuntime-Independent Extensions on Windows

Solve (rather stupid):
Don’t use ruby’s includes and libs. Use Win32 API
GetProcAddress(hmodule, strFunction) to locate ruby’s C-APIs.

The following is a simple experiment with VC2008 Express and
ruby191-mswin32_90 and ruby191-mingw32:


#include <stdio.h>
#include <windows.h>

void Init_ho() {
HMODULE h = 0;
FARPROC p = 0;

// why they create so many dll names ...?
if(!h) h = GetModuleHandle("msvcrt-ruby191.dll");
if(!h) h = GetModuleHandle("msvcrt60-ruby191.dll");
if(!h) h = GetModuleHandle("msvcrt70-ruby191.dll");
if(!h) h = GetModuleHandle("msvcrt80-ruby191.dll");
if(!h) h = GetModuleHandle("msvcrt90-ruby191.dll");
if(!h) h = GetModuleHandle("msvcrt100-ruby191.dll");
// and many others ...

if(!h) {

p = GetProcAddress(h, "rb_io_check_readable");
// and may others ...

/* if imported functions are the same in ruby1.8 and ruby1.9,
   then a cross-version extension ? */

if(p) {




building commands are (not using extconf.rb)
cl -c ho.c
cl -LD -MD ho.obj user32.lib -link -def:ho.def

some explanations of the commands:
-LD : link dll
-MD : statically link
-Fe : output file name
-link -def:ho.def : make entry point Init_ho searchable for ruby

require ‘’ will simply print “loaded” on console.
Both ruby191-mswin32_90 and ruby191-mingw32 can load it properly.