Hey guys,

rb_define_class_under() appears to be seriously broken on WIN32 (Microsoft Visual 
C++ 6.0 sp5) builds.  The same code I have works fine when built with g++/gcc on my 
Linux box.  Here is the quick breakdown:

rb_define_class_under() executes it's first few lines of code, and then passes 
control over to rb_define_class_id() which proceeds to segfault on the following 
line:  

RBASIC(klass)->klass = rb_singleton_class_new(RBASIC(super)->klass);

Unfortunately, I am relatively new to the Ruby code base and haven't been able to 
figure out what the cause of this problem is, but I can reproduce it 100% of the 
time and this happens with both 1.6.4 and the nightly 1.7.x snapshot.

Below is the code I am using that exhibits the problem.  I also have a few programs 
available that I used to narrow the problem down at this url:

http://strider.terralab.com/~bryan/rb-cpp-test.zip

SWIG makes consistent use of this function, so this could be a problem for anybody 
porting their SWIG modules to WIN32 (otherwise I'd just work around it).

Should I also submit this as a bug report?

Thanks,
Bryan

--[SNIP]--


Build:
cl.exe -nologo -DWIN32 -Zi -MD -O2b2xg- -G5 -GR -GX -Fm test4.cpp mswin32-
ruby16.lib -link /STACK:0x2000000

test4.cpp:
#include <iostream.h>
#include "ruby.h"

class ITestSwig
{
public:
        ITestSwig();
        virtual ~ITestSwig();

        virtual int Multiply(int, int) = 0;
};

class CTestSwig:
        public ITestSwig
{
public:
        CTestSwig();
        virtual ~CTestSwig();

        virtual int Multiply(int, int);
};

ITestSwig::ITestSwig()
{
        cout << "ITestSwig::Constructor" << endl;
}

ITestSwig::~ITestSwig()
{
        cout << "ITestSwig::Destructor" << endl;
}

CTestSwig::CTestSwig()
{
        cout << "CTestSwig::Constructor" << endl;
}

CTestSwig::~CTestSwig()
{
        cout << "CTestSwig::Destructor" << endl;
}

int CTestSwig::Multiply(int a, int b)
{
        return a * b;
}

VALUE rbModule, cTestSwig;

VALUE wrap_Multiply(VALUE self, VALUE a, VALUE b)
{
        CTestSwig *c;

        Data_Get_Struct(self, CTestSwig, c);

        int r = c->Multiply(NUM2INT(a), NUM2INT(b));

        return INT2NUM(r);
};

void wrap_FREE(void *p)
{
        CTestSwig *c = (CTestSwig *)p;

        delete c;
}

VALUE wrap_NEW(VALUE clss)
{
        CTestSwig *c = new CTestSwig();

        VALUE t = Data_Wrap_Struct(clss, 0, wrap_FREE, c);

        rb_obj_call_init(t, 0, NULL);

        return t;
}

#define RB_FUNC(func) ((VALUE (*)__(()))func)

int main(int argc, char **argv)
{
        ruby_init();

        ruby_script("embedded");

        rbModule = rb_define_module("TestSwig");

        cTestSwig = rb_define_class_under(rbModule, "CTestSwig", rb_cObject);
        rb_define_singleton_method(cTestSwig, "new", RB_FUNC(wrap_NEW), 0);
        rb_define_method(cTestSwig, "Multiply", RB_FUNC(wrap_Multiply), 2);

        rb_load_file("test4.rb");

        ruby_run();

        return 0;
}

test4.rb:
obj = TestSwig::CTestSwig.new()

print "4 * 22 = " + obj.Multiply(4,22).to_s