Joel VanderWerf wrote:

>    rb_eval_string("$stdout.reopen ...");

Here ya go, homeboy:

#include <string>
#include <iostream>
#include <fstream>
#include <assert.h>
#include "C:\ruby\lib\ruby\1.8\i386-mswin32\ruby.h"
#pragma comment(lib, "C:/ruby/lib/msvcrt-ruby18.lib")

    using std::string;
    using std::cout;
    using std::endl;
    using std::ifstream;
    using std::getline;

static string error_print(int state)
{
    VALUE eclass;
    VALUE einfo;
    char buff[BUFSIZ];

#define TAG_RETURN 0x1
#define TAG_BREAK 0x2
#define TAG_NEXT 0x3
#define TAG_RETRY 0x4
#define TAG_REDO 0x5
#define TAG_RAISE 0x6
#define TAG_THROW 0x7
#define TAG_FATAL 0x8
#define TAG_MASK 0xf

    switch (state) {
    case TAG_RETURN:  return ("E267: unexpected return");
    case TAG_NEXT:    return ("E268: unexpected next");
    case TAG_BREAK:   return ("E269: unexpected break");
 case TAG_REDO:    return ("E270: unexpected redo");
    case TAG_RETRY:   return ("E271: retry outside of rescue clause");
    case TAG_RAISE:
    case TAG_FATAL:
     eclass = CLASS_OF(ruby_errinfo);
     einfo = rb_obj_as_string(ruby_errinfo);
     if (eclass == rb_eRuntimeError && RSTRING(einfo)->len == 0) {
         return ("E272: unhandled exception");
     }
     else {
         VALUE epath;
         char *p;

         epath = rb_class_path(eclass);
         snprintf(buff, BUFSIZ, "%s: %s",
          RSTRING(epath)->ptr, RSTRING(einfo)->ptr);
         p = strchr(buff, '\n');
         if (p) *p = '\0';
         return (buff);
     }

    default:
     snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state);
     return (buff);

    }
}


int main(int argc, char* argv[])
{

#if defined(NT)
    NtInitialize(&argc, &argv);
#endif

    ruby_init();
    ruby_script("embedded");

    int state(0);
    rb_eval_string_protect("$stdout.reopen(File.open('c:/temp/redirect.txt',
'w'))\n", &state);
    if (state)  {  cout << error_print(state) << endl;  return 1;  }

    rb_eval_string_protect("puts 'hello world'\n", &state);
    if (state)  {  cout << error_print(state) << endl;  return 1;  }

    rb_eval_string_protect("$stdout.flush()\n", &state);
    if (state)  {  cout << error_print(state) << endl;  return 1;  }

    ifstream file ("c:/temp/redirect.txt");
    string line;
    getline(file, line);
    assert ("hello world" == line);

    return 0;
}

The two clues were - protect the evaluation, so when it dies on "file not
open" we get a clean error message, and redirect inside Ruby, not outside
where it's hard.

Now I work on replacing the temporary file with a data sink back into my C++
source.

-- 
  Phlip
  http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces