From: Phlip Date: 2004-08-25T15:15:39+09:00 Subject: Re: redirect stdout for embedded Ruby Joel VanderWerf wrote: > rb_eval_string("$stdout.reopen ..."); Here ya go, homeboy: #include #include #include #include #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