さくです。

ruby-listよりはruby-extのような気もするのですが、ひとまずlistのほうへ出
します。
extって拡張ライブラリを作るためのMLだけど、rubyを埋め込むほうも可でしょ
うか?

Windows98環境でC++の正規表現クラスRegexpが欲しくなったので、rubymw.dllを
使って作ってるのですが、以下にあるメンバ関数matchを数千回呼び出すうちに、
アクセス違反が生じます。

ソースを追ってみたのですが、

gc.cのrb_gc_mark()にてobjが不正
reex.cのinit_regs()にてregsが不正

など止まるところがまちまちなので困っています。

たぶん、C++のコード中で作成したRubyオブジェクト(VALUE)の管理がうまく行え
ていなくてGCとの不整合が起こってるんじゃないかとは思うのですが……。

Regex.hはこんな感じです。現在必要なのがマッチングだけなので、以下でほぼ
全てです。
何かマズいことをやっているところがあったら指摘していただけるとありがたい
です。

namespace ruby {

#include <string>
#include <stdexcept>
using namespace std;
#include "ruby.h"

    // ruby_init()の呼び出しを隠すために作ったObjectクラス
    class Object
    {
        static bool rubyInitialized; // Object.cppにて falseに初期化
    public:
        Object()
        {
            if ( ! rubyInitialized) {
                ruby_init();
                rubyInitialized = true;
            }
        }
        virtual ~Object() { }
    }
    
    // 正規表現に関するC++例外
    class RegexpException : public runtime_error { ... };

    class Regexp : public Object
    {
        // rb_protectに渡すために引数をまとめる構造体
        struct reg_arg
        {
        public:
            reg_arg(const char* str, size_t length, int flags)
                : str_(str), length_(length), flags_(flags) { }
            const char* str_;
            size_t length_;
            int flags_;
        };
        // rb_protectに渡して正規表現オブジェクトを作る関数
        static VALUE make_reg(reg_arg* arg)
        {
            return rb_reg_new(arg->str_, arg->length_, arg->flags_);
        }
        // コンストラクタ & デストラクタ
        Regexp(const string& s, int flags=0)
        {
            reg_arg arg(s.c_str(), s.size(), flags);
            regexp_ = rb_protect((VALUE (*)())make_arg, (VALUE)&arg, 0);
            if (NIL_P(regexp_)) {
                regexp_ = 0;
                throw RegexpException(s);
            }
            rb_global_variable(&regexp_);
        }
        virtual ~Regexp() { }
    
        // string sとマッチした位置を返す。マッチしなければnpos(=-1)を返す。
        string::size_type match(const string& s)
        {
            if (regexp_) {
                VALUE str = rb_str_new2(s.c_str());
                VALUE result = rb_reg_match(regexp_, str);
                if (NIL_P(result)) {
                    return string::npos; // マッチしなかった。
                }
                return NUM2INT(result); // マッチ位置
            } else {
                return string::npos;
            }    
        }
    private:
        VALUE regexp_;
    };
} // namespace ruby