From: Daniel Berger Date: 2007-06-20T00:24:25+09:00 Subject: Re: Problem wrapping the C++ STL On Jun 19, 1:07 am, Sylvain Joyeux wrote: > > g++ -Wall -I. -I/opt/lib/ruby/1.8/i686-darwin8.9.1 > > -I/opt/lib/ruby/1.8/i686-darwin8.9.1 -I. -fno-common -g -O2 -pipe > > -fno-common -c cvector.c > > cvector.c: In function 'void Init_cvector()': > > cvector.c:10: error: invalid conversion from 'VALUE (*)(int, VALUE*, > > VALUE)' to 'VALUE (*)(...)' > > cvector.c:10: error: initializing argument 3 of 'void > > rb_define_method(VALUE, const char*, VALUE (*)(...), int)' > > make: *** [cvector.o] Error 1 > > C++ is more pissy than C about type convertions. You have to use the > RUBY_METHOD_FUNC macro to convert cvector_init into the right type: > > rb_define_method(cVector, "initialize", > RUBY_METHOD_FUNC(cvector_init), -1); Ah, thanks. > > > Note that you can wrap std::vector directly (no need to go through an > > > intermediate cvector structure) > > > I guess I could store it as an instance variable within the constructor > > and refer back to it that way. I don't think it's faster, though. Or, > > did you have something else in mind? > > The idea is *not* to use a cvector structure. Since you'll have to provide > an alloc/free method pair anyway, allocate std::vector in them. Check > value_set_alloc/value_set_free inhttp://www.laas.fr/~sjoyeux/darcs/utilrb/ext/value_set.cc Interesting, thank you. For kicks, I tried to compile your source code on my Solaris 10 box (after installing boost). It built (with some warnings), but I can't get it to load. Here's the extconf.rb file I used: require 'mkmf' dir_config('set2') case RUBY_PLATFORM when /sunos|solaris/ CONFIG['CC'] = 'CC' when /mswin/i CONFIG["COMPILE_C"].sub!(/-Tc/, '-Tp') else CONFIG['CC'] = 'g++ -Wall' end create_makefile('set2') Here was the result of the build step: djberge-/export/home/djberge/workspace/set/ext-635>ruby extconf.rb -- with-set2-include=/opt/csw/include creating Makefile djberge-/export/home/djberge/workspace/set/ext-636>make CC -I. -I/usr/local/lib/ruby/1.8/sparc-solaris2.10 -I/usr/local/lib/ ruby/1.8/sparc-solaris2.10 -I. -I/opt/csw/include -KPIC -dalign -fns - xbuiltin=%all -xlibmil -xtarget=ultra2e -xO5 -xipo -c set.c "set.c", line 349: Warning (Anachronism): Formal argument 3 of type extern "C" unsigned long(*)(...) in call to rb_iterate(extern "C" unsigned long(*)(unsigned long), unsigned long, extern "C" unsigned long(*)(...), unsigned long) is being passed unsigned long(*)(...). "set.c", line 369: Warning (Anachronism): Formal argument 2 of type extern "C" unsigned long(*)(unsigned long) in call to rb_define_alloc_func(unsigned long, extern "C" unsigned long(*) (unsigned long)) is being passed unsigned long(*)(unsigned long). 2 Warning(s) detected. ld -G -o set2.so set.o -L'.' -L'/usr/local/lib' -R'/usr/local/lib' - L. -lrt -lpthread -ldl -lcrypt -lm -lc Ok, a couple warnings. I proceed to try to "require 'set2'" and I get this: djberge-/export/home/djberge/workspace/set/ext-637>ruby test.rb /export/home/djberge/workspace/set/ext/set2.so: ld.so.1: ruby: fatal: relocation error: file /export/home/djberge/workspace/set/ext/set2.so: symbol __1cDstdJbad_allocG__vtbl_: referenced symbol not found - / export/home/djberge/workspace/set/ext/set2.so (LoadError) from /usr/local/lib/ruby/site_ruby/1.8/rubygems/ custom_require.rb:27:in `require' from test.rb:2 This was with Ruby 1.8.6-p38 (today's svn checkout of the 1.8.6 branch). Any ideas? Dan