Path: news.mathworks.com!newsfeed-00.mathworks.com!nlpi057.nbdc.sbc.com!prodigy.net!news2!news.glorb.com!news.aset.psu.edu!support1-1.mathforum.org!not-for-mail
From: Bill August <hui.song@beds.ac.uk>
Newsgroups: comp.soft-sys.matlab
Subject: Re: C++ mex question
Date: Thu, 09 Oct 2008 08:00:47 EDT
Organization: The Math Forum
Lines: 186
Message-ID: <21918034.1223553677507.JavaMail.jakarta@nitrogen.mathforum.org>
References: <5b850fc6-660d-420f-ba1c-f417c29a3046@m45g2000hsb.googlegroups.com>
NNTP-Posting-Host: nitrogen.mathforum.org
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Trace: support1-1.mathforum.org 1223553677 10263 144.118.30.135 (9 Oct 2008 12:01:17 GMT)
X-Complaints-To: news@mathforum.org
NNTP-Posting-Date: Thu, 9 Oct 2008 12:01:17 +0000 (UTC)
Xref: news.mathworks.com comp.soft-sys.matlab:494228


> On Sep 2, 10:25 am, Bill August <hui.s...@beds.ac.uk>
> wrote:
> > > Hi,
> >
> > > I am using Matlab R2008a 64 bit and MSVC++ 9.0
> > > (Visual
> > > Studio 2008) on Windows Vista 64 bit. I compile
> the
> > > following mex function
> >
> > > #include "mex.h"
> > > #include <iostream>
> > > using namespace std;
> >
> > > extern "C"
> > > void mexFunction(int nlhs,mxArray *plhs[],int
> > > nrhs,const
> > > mxArray *prhs[])
> > > {
> > >     cout << "Test" << endl << flush;
> > >     //printf("Test\n");
> > > }
> >
> > > The cout doesn't result in anything being
> displayed.
> >
> > > Section 26 of the tech note
> >
> >http://www.mathworks.com/support/tech-notes/1600/1605
> .
> > > html
> >
> > > does say "Using cout will not work as expected in
> C++
> > > MEX-
> > > files. This is because cout is expecting to use a
> > > display
> > > that is not MATLAB. To workaround this problem,
> use
> > > mexPrintf instead.". However,
> > > 1. This mex function works with Matlab R14 and
> MSVC++
> > > 7.1
> > > (Visual Studio 2003) on Windows XP.
> > > 2. I am using some C++ template libraries that
> use
> > > cout. So
> > > I cannot change them to mexPrintf.
> > > 3. The commented printf call works. Aren't cout
> and
> > > printf
> > > using the same output device?
> >
> > > Thank you for your help.
> >
> > > Siva
> >
> > Hi Siva,
> > My solution is to open a new console window for
> cout. It may help you to solve the problem.
> > Regards.
> >
> > ------file coutdemo.cpp-----
> > // Usage:
> > //        show how to open a console window for
> matlab to handle cout message
> > // Input:
> > //        none
> > // Output:
> > //        none
> >
> > #include "mex.h"
> > #include <windows.h>
> > #include <iostream>
> > #include "guicon.h"
> > using namespace std ;
> >
> > void mexFunction(int nlhs, mxArray *phs[], int
> nrhs, const mxArray *prhs[])
> > {
> >         // redirect
> >         RedirectIOToConsole();
> >         // print
> >         cout<<"cout demo"<<endl;
> >         // wait for kill
> >         cin.get() ;
> >         // kill the console
> >         FreeConsole() ;
> >
> > }
> >
> > -----file guicon.h------
> > #ifndef __GUICON_H__
> > #define __GUICON_H__
> > #ifdef _DEBUG
> >
> > void RedirectIOToConsole();
> >
> > #endif
> > #endif
> > /* End of File */
> >
> > -----file guicon.cpp------
> > #include <windows.h>
> > #include <stdio.h>
> > #include <fcntl.h>
> > #include <io.h>
> > #include <iostream>
> > #include <fstream>
> > #ifndef _USE_OLD_IOSTREAMS
> > using namespace std;
> > #endif
> >
> > // maximum mumber of lines the output console
> should have
> > static const WORD MAX_CONSOLE_LINES = 500;
> > #ifdef _DEBUG
> >
> > void RedirectIOToConsole()
> > {
> > int hConHandle;
> > long lStdHandle;
> > CONSOLE_SCREEN_BUFFER_INFO coninfo;
> > FILE *fp;
> >
> > // allocate a console for this appAllocConsole();
> >
> > // set the screen buffer to be big enough to let us
> scroll text
> >
> GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HAN
> DLE), &coninfo);
> > coninfo.dwSize.Y = MAX_CONSOLE_LINES;
> >
> SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HAN
> DLE),
> > coninfo.dwSize);
> >
> > // redirect unbuffered STDOUT to the console
> > lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
> > hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
> > fp = _fdopen( hConHandle, "w" );
> > *stdout = *fp;
> > setvbuf( stdout, NULL, _IONBF, 0 );
> >
> > // redirect unbuffered STDIN to the console
> > lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
> > hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
> > fp = _fdopen( hConHandle, "r" );
> > *stdin = *fp;
> > setvbuf( stdin, NULL, _IONBF, 0 );
> >
> > // redirect unbuffered STDERR to the console
> > lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
> > hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
> > fp = _fdopen( hConHandle, "w" );
> > *stderr = *fp;
> > setvbuf( stderr, NULL, _IONBF, 0 );
> >
> > // make cout, wcout, cin, wcin, wcerr, cerr, wclog
> and clog
> > // point to console as well
> > ios::sync_with_stdio();}
> >
> > #endif
> > /* End of File */
> 
> Bill, what do you with the console after the
> mexFunction returns? If I
> call the mex file again, the call to AllocConsole
> fails ("access
> denied" and no GetStdHandle) and no output to the
> existing console is
> possible, unfortunately, I don't understand why. So,
> I free the
> console first and allocate a new one. The questions
> is how to reuse
> the console between different mexFunction
> invocations?
> Igor
Hi Igor,
It is quite easy to solve this probelm.
The idea is to return the handles of the console.
You can visit my blog for details.
beljsl.blogspot.com
Good luck.