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