Solved

Using a compiler from within C# runtime code

Posted on 2002-05-20
5
264 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying 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

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
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 learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

710 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