------art_8184_11463452.1201506638655
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Here are some hurdles that I overcame when coding a Ruby Extension in C++ on
Win32. Feel free to add to this or to comment. I hope it will help someone
someday. (If you ask WHY?, my answer is: I'm very comfy with STL).

1. For Win32, mkmf generates makefiles for Visual Studio. In other words,
"make" won't work for you on Win32, you have to type "nmake". I used VC6.
And to use C++, the files you compile must be named ".cpp", not ".c" so that
they are compiled as c++ files instead of c files. Perhaps .cc extension
works, I didn't try.

2. Your static functions cannot be passed down to rb_define_method,
rb_define_global_function etc. The solution is not obvious. My first
thought, extern "C", __cdecl/__stdcall etc, does not do _anything_ to solve
it. You have to do the following (found somewhere on net):

// first a typedef
typedef VALUE (*HOOK)(...);
// then do a reinterpret_cast:
rb_define_method(rb_cYadaYada, "initialize",
reinterpret_cast<HOOK>(yadayada_initialize), 2);

3. Destructors in the functions are not called if ruby long jumps out! This
happens when you raise an exception. Here is an example using the classical
Lock-A-Mutex when the object is created, and Unlock-A-Mutex when the
destructor is called:

  Lock my_lock(mutex);

  connected  b_iv_get(self, "@connected");

  if(connected ! true)
  {
    rb_raise(rb_eRuntimeError, YadaYada is not connected");
  }

When the exception is raised, the destructor of my_lock WILL NOT BE CALLED
so the Mutex is not unlocked. Nasty!

4. You have to #include <string> before <ruby.h>. Otherwise you will get a
lot of compile errors when #include:ing <string>. This might apply to other
include files, but it seemed not to apply to <map> and <list>.

Cheers/D

------art_8184_11463452.1201506638655--