Thread: Calling GNUPLOT plot routines from WINDOWS app

  1. #1
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24

    Calling GNUPLOT plot routines from WINDOWS app

    Hello everyone,

    I'm rather stuck on an interesting problem and need some guidance. Suppose I have a WINDOWS app which allows the user to plot results from a computation. Suppose further that the plotting is to be done using GNUPLOT (wgnuplot.exe). The user app allows the specification of certain GNUPLOT options. These and the calls to GNUPLOT routines should be handled internally by the APP so that the user avoids writing results to a text file and then subsequently running GNUPLOT on the external file. Some sort of Interprocess Communication is required...

    Now, if I were writing a call to GNUPLOT from a console app the matter is tricky but soluble. I would use _POPEN() followed by fprintf()'s to send GNUPLOT commands. But, my app is not a console, it is a WINDOWS app and according to MSDN _popen() won't work. They're right,too.

    It seems as if I need to do something like create an anonymous pipe and send GNUPLOT commands via the pipe to a GNUPLOT process created with a call to CreateProcess(). Or something like that. After this, everything gets even muddier to me.

    If someone has solved this problem, I'm a happy customer.

    Regars,
    Mark Allyn

  2. #2
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Quote Originally Posted by allynm View Post
    But, my app is not a console, it is a WINDOWS app and according to MSDN _popen() won't work. They're right,too.

    If someone has solved this problem, I'm a happy customer.
    Read the second sentence of that part of the _popen docs. That link shows the method you should use, but instead of their WriteToPipe() just sprintf() your data and then WriteFile() to your equivalent of g_hChildStd_IN_Wr.

  3. #3
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24
    Hello AdeyBlue,

    Prior to reading your response, I previously I had read the second sentence in the _popen doc and followed the link to MSDN's example. After some fooling around, I got the thing to work as given in the original code.

    In the original, the program directs a text file to the child process and the child process prints it out, followed by a brief message from it.

    I'm not clear on quite how this is supposed to work in the case of GNUPLOT. Are you suggesting that the text file should contain GNUPLOT commands? Or are you suggesting that each of the commands would be sprintf()'d and each written individually to GNUPLOT.exe? Also, I don't understand how to write the parameters for CreateProcess(), especially parameter 1 and parameter 2, (i.e. lpApplicationName and lpCommandLine,...). The Application Name is GNUPLOT.exe, but what is lpCommandLine in this particular case.

    Sorry for the newb questions.

    Thanks,
    Mark Allyn

  4. #4
    Make Fortran great again
    Join Date
    Sep 2009
    Posts
    1,413
    I would use something else besides gnuplot, because it's a slow and buggy piece of garbage. GNU Octave uses this as the default plotting backend and they would definitely have more users if they got rid of that piece of $%#@^.

  5. #5
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24
    Hello Epy,

    I'm not "married" to GNUPLOT or OCTAVE, although I have used both as stand-alone applications with good results. What alternatives can you suggest that would interface with Windows?

    Mark Allyn

  6. #6
    Make Fortran great again
    Join Date
    Sep 2009
    Posts
    1,413
    I was actually just looking because there aren't a whole lot of great alternatives. I use matplotlib (Python library) at work because it probably makes the cleanest looking plots of what's out there. You could make a small Python script to read data from a file (or stdin, whichever) and create your plots. PLplot has language bindings for just about everything, but it's not as clean looking as matplotlib.
    Last edited by Epy; 01-24-2012 at 08:55 PM. Reason: at -> as

  7. #7
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24
    Hello Epy,

    If I follow your line of reasoning correctly, then I can accomplish the same thing using straight C and calling the WINDOWS API CreateProcess(). In this case the App name is Gnuplot.exe and the command is to load a file containing Gnuplot commands, "plot" in particular:



    Code:
    #include <windows.h>
    #include <tchar.h>
    
    int main(int argc, char * argv[])
    {
    STARTUPINFO StartInfo;
    PROCESS_INFORMATION ProcInfo ;
    LPCTSTR plotter= "c:\\gnuplot\\bin\\wgnuplot.exe" ;
    TCHAR command[ ] = TEXT("load c:\\mingw\\mycode\\mypgm\\gnufile.plt") ;
    GetStartupInfo(&StartInfo) ;
    
    if(CreateProcess(plotter, command,
      NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL,
         NULL, &StartInfo, &ProcInfo)==FALSE) 
    	MessageBox(NULL, TEXT("Didn't Create"), TEXT("Create Proc Status"), MB_OK);
    system("PAUSE") ;
    return 0 ;
    }
    Is this approach what you had in mind using Python? If so, what would the advantages be to using Python?

    Thanks
    Mark

  8. #8
    Registered User
    Join Date
    Apr 2010
    Location
    hellertown, pennsylvania
    Posts
    24
    Hello all,

    Well, for the sake of the record and perhaps help someone else who has stumbled on this problem, I have finally got code that does what I want. Here it is:

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>
    
    int _tmain (int argc, LPTSTR argv [])
    
    {
    	DWORD i;
    	HANDLE hReadPipe, hWritePipe;
    	
    	SECURITY_ATTRIBUTES PipeSA = {sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
    			/* Init for inheritable handles. */
    	TCHAR outBuf[ ] = TEXT("a=2; plot sin(a*x)/x; pause mouse; plot exp(-a*x); pause mouse") ;	
    	TCHAR inBuf[80];
    	DWORD dwWritten, dwRead ;
    	BOOL  bSuccess = FALSE;
    	PROCESS_INFORMATION  ProcInfo2;
    	STARTUPINFO StartInfoCh2;
    	
    
    	/* Startup info for the Gnuplot process. */
    
    	GetStartupInfo (&StartInfoCh2);
    
    	/* Create an anonymous pipe with default size.
    		The handles are inheritable. */
    
    	bSuccess = CreatePipe (&hReadPipe, &hWritePipe, &PipeSA, 0);
    	if (bSuccess == TRUE) printf("pipe created\n");
    
    	WriteFile(hWritePipe, outBuf, sizeof(outBuf), &dwWritten, NULL) ;	
    	printf("Wrote %d bytes to Gnuplot\n", dwWritten) ;
    	
    	CloseHandle (hWritePipe);
    	
    	/* Repeat (symmetrically) for the child process. */
    
    	StartInfoCh2.hStdInput  = hReadPipe;
    	StartInfoCh2.hStdError  = GetStdHandle (STD_ERROR_HANDLE);
    	StartInfoCh2.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
    	StartInfoCh2.dwFlags = STARTF_USESTDHANDLES;
    	bSuccess = FALSE ;
    	bSuccess = CreateProcess ("c:\\gnuplot\\bin\\pgnuplot.exe", NULL, NULL, NULL,
    			TRUE,0, NULL, NULL, &StartInfoCh2, &ProcInfo2);
    	if (bSuccess == TRUE)
    	  printf("Created Gnuplot Process\n" ) ;
    	
    	WaitForSingleObject (ProcInfo2.hProcess, INFINITE);
    	CloseHandle (ProcInfo2.hThread); 
    	CloseHandle (hReadPipe);
    
    	/* Wait for Gnuplot process to complete.*/
    	
    	CloseHandle (ProcInfo2.hProcess);
    	return 0;
    }
    AdeyBlue's overall notion is reflected in the above use of anonymous pipe. This is rather an ugly solution in that the TEXT message to plot something isn't easily constructed from the GUI itself; someone might have a prettier solution and I'd be interested to see it.

    Regards,
    Mark Allyn

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Windows Api calling in[ Borland C ]
    By maj0 in forum C Programming
    Replies: 2
    Last Post: 03-25-2010, 03:42 AM
  2. More *nix pipe blues.. I can't get gnuplot to display the plot.
    By Overworked_PhD in forum Linux Programming
    Replies: 1
    Last Post: 02-14-2010, 09:52 PM
  3. Calling raw windows API using borland
    By TiMBuS in forum C++ Programming
    Replies: 3
    Last Post: 06-16-2005, 08:46 AM
  4. calling an external program from within a windows GUI
    By korbitz in forum Game Programming
    Replies: 1
    Last Post: 03-16-2004, 10:39 PM
  5. Calling C++ routines from C?
    By snoopdog in forum C Programming
    Replies: 1
    Last Post: 03-04-2002, 03:28 AM