Solved

Using a compiler from within C# runtime code

Posted on 2002-05-20
5
242 Views
Last Modified: 2012-05-04
I am writing a program in Builder 4 which creates a text skeleton of a program from an object diagram. I want to be able to compile this from within my program using something like the GNU free mingw32 compiler when the user clicks some button. Any suggestions?

Secondly can I get access to any output error messages etc? Ideally I would like this to appear to run as part of my own program rather than opening the dos window and being a separate entity. I want to give the user feedback from the compiler without them having to go back to my program for themselves. Is this possible?
0
Comment
Question by:jukev
  • 2
  • 2
5 Comments
 

Expert Comment

by:BitTwiddler
ID: 7021858
You could create the process with CreateProcess() and use the hStdInput, hStdOutput, and hStdError fields of the STARTUP_INFO struct you pass to CreateProcess().  This would allow you to grab the input, output, and error information from the compiler.  A simple example follows...

    startInfo.dwFlags     = STARTF_USESTDHANDLES;
    startInfo.hStdInput   = GetStdHandle(STD_INPUT_HANDLE);
    startInfo.hStdOutput  = GetStdHandle(STD_OUTPUT_HANDLE);
    startInfo.hStdError   = GetStdHandle(STD_ERROR_HANDLE);

    b = CreateProcess(
            progname,
            buf,
            NULL,
            NULL,
            TRUE,
            0,
            NULL,
            NULL,
            &startInfo,
            &pidInfo);

The example isn't complete, as you'd need to fill in additional fields of startInfo, pidInfo, etc., but this should get you going in the right direction.

HTH
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7022790
Hi BitTwiddler,
Welcome to EE!
The experts in this section have agreed to post Comments rather than Answers.  That prevents the question from being 'locked' -- keeps the question in the upper part of the list so that more experts will see it and provide help.

As you said yourself, your post is not a complete answer, and nothing less than a 'complete and only-possible valid' solution should be marked as an 'Answer'.

So in the future, please post Comments, like everybody else.  Thanks!

-- Dan
0
 

Author Comment

by:jukev
ID: 7023405
No offence BitTwiddler but I need a bit more help than this. At least a bit of an explanation of  what that code does. I will have a go with what you have submitted but I want to open this back up to see if you or anyone else can give me a bit more info
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 200 total points
ID: 7023492
jukey,
Here is a useful utility function that actually does all that you want:

CString ExecAndGetOutput(LPCSTR szCommand, LPCSTR szParms )
{
     CString sRet= "";
     SECURITY_ATTRIBUTES rSA;
     rSA.nLength=              sizeof(SECURITY_ATTRIBUTES);
     rSA.bInheritHandle=       TRUE;
     rSA.lpSecurityDescriptor= 0;

     HANDLE hReadPipe, hWritePipe;
     CreatePipe( &hReadPipe, &hWritePipe, &rSA, 250000 );
   
    PROCESS_INFORMATION rPI;
     STARTUPINFO rSI;
    memset( &rSI, 0, sizeof(STARTUPINFO));
    rSI.cb=          sizeof(STARTUPINFO);
     rSI.dwFlags=     STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES;
     rSI.wShowWindow= SW_NORMAL; // SW_HIDE; //SW_MINIMIZE;
     rSI.hStdOutput=  hWritePipe;
     rSI.hStdError=   hWritePipe;

     CString sCmd; sCmd.Format( "%s %s", (LPCSTR)szCommand, (LPCSTR)szParms );

     BOOL fRet=CreateProcess(NULL,(LPSTR)(LPCSTR)sCmd, NULL,NULL,TRUE,0,0,0, &rSI, &rPI );
     if ( !fRet ) {
          return( "" );
     }
     //------------------------- wait for the program to end
     WaitForSingleObject( rPI.hProcess, INFINITE);

     //------------------------- read the pipe
     char dest[1000];
     while ( ReadFromPipeNoWait( hReadPipe, dest, sizeof(dest) ) > 0 ) {
          sRet += dest;
     }

     CloseHandle( hReadPipe  );
     CloseHandle( hWritePipe );
     CloseHandle( rPI.hThread);
     CloseHandle( rPI.hProcess);
     return( sRet );
}
//-----------------------------------------------
int ReadFromPipeNoWait( HANDLE hPipe, char* pDest, int nMax )
{
     DWORD nBytesRead= 0;
     DWORD nAvailBytes;
     char cTmp;
     memset( pDest, 0, nMax );

     PeekNamedPipe( hPipe, &cTmp, 1, NULL, &nAvailBytes, NULL );
     if ( nAvailBytes == 0 ) {
          return( nBytesRead );
     }
     BOOL fNoErr= ReadFile( hPipe, pDest, nMax-1, &nBytesRead, NULL);

     if ( !fNoErr ) {  // error
          nBytesRead= 0;
          // MessageBox("Error reading pipe");
     }
     return( nBytesRead );
}

It uses a few MFC classes, but of course, the program that you compile would not need to use MFC, and it's not too hard to convert it to different classes such as std::string or just char array buffers.

To use the function, call like this:

CString sProgOutput=
ExecAndGetOutput( "c:\\mydir\\mingw32.exe", "abc.cpp" );

The final parameter needs to be a string containing all of the command-line parameters typically used to execute the mingw32 compiler (or whatever free compiler you end up selecting) and compile a particular module.  You will need to research that yourself.

-- Dan
0
 

Author Comment

by:jukev
ID: 7025799
thanx so much
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question