Solved

Using a compiler from within C# runtime code

Posted on 2002-05-20
5
221 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
thanx so much
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

744 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now