Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Using a compiler from within C# runtime code

Posted on 2002-05-20
5
Medium Priority
?
271 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 800 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
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 goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

782 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