You are here: Home Help/User Support Programming (C, FORTRAN, etc.) Adding Fortran subroutines to wxWindows GUI code

Adding Fortran subroutines to wxWindows GUI code

As mentioned in the mixed-languages notes, you may need to add a C++ graphical user interface to existing Fortran numerical codes. For the purposes of this note, we'll focus on using the cross-platform wxWindows toolkit, available for Windows and Unix platforms, with MacOS support coming soon. Currently, the wxWindows toolkit is only installed on GNU/Linux systems in the CAE Lab.

Program Structure and Code

We'll call FORTRAN subroutines as necessary from the C++ code, as documented in the mixed-languages notes. The C++ code is based on Robert Roebling's Hello, World tutorial. The only additions or changes include the following:

  1. extern "C" declaration for FORTRAN subroutine, in the same form as shown in the mixed-language notes:
             extern "C" {
               void setab_(int *a, int *b);
             }
    
  2. Addition of variables length, a, b, and status involved in the creation of the status bar text:
             int length, a, b;
             char status[50];
    
  3. Replacement of a simple static SetStatusText() call with:
             setab_(&a,&b);
             length=sprintf(status, "Welcome to wxWindows: a=%d, b=%d", a, b);
             if (length<=50) {
               SetStatusText(status);
             }
             else {
               SetStatusText("Welcome to wxWindows: a and b not set due to string overflow");
             }
    

File hw-wx.C

Store the following code in the file 'hw-wx.C':

  extern "C" {
    void setab_(int *a, int *b);
  }

  #include "wx/wx.h"
  class MyApp: public wxApp {
    virtual bool OnInit();
  };

  class MyFrame: public wxFrame {
  public:

    MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size);

    void OnQuit(wxCommandEvent &event);
    void OnAbout(wxCommandEvent &event);

    DECLARE_EVENT_TABLE()
  };

  enum {
    ID_Quit = 1,
    ID_About,
  };

  BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_MENU(ID_Quit, MyFrame::OnQuit)
  EVT_MENU(ID_About, MyFrame::OnAbout)
  END_EVENT_TABLE()

  IMPLEMENT_APP(MyApp)

  bool MyApp::OnInit() {
    MyFrame *frame = new MyFrame( "Hello, World", wxPoint(50,50), wxSize(450,340) );
    frame->Show(TRUE);
    SetTopWindow(frame);
    return TRUE;
  }

  MyFrame::MyFrame(const wxString &title,
                   const wxPoint &pos,
                   const wxSize &size):
    wxFrame((wxFrame *)NULL, -1, title, pos, size) {

    int length, a, b;
    char status[50];

    wxMenu *menuFile = new wxMenu;
    menuFile->Append(ID_About, "&About...");
    menuFile->AppendSeparator();
    menuFile->Append(ID_Quit, "E&xit");

    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append(menuFile, "&File");
    SetMenuBar(menuBar);
    CreateStatusBar();

    setab_(&a,&b);
    length=sprintf(status, "Welcome to wxWindows: a=%d, b=%d", a, b);
    if (length<=50) {
      SetStatusText(status);
    }
    else {
      SetStatusText("Welcome to wxWindows: a and b not set due to string overflow");
    }

  }

  void MyFrame::OnQuit(wxCommandEvent &WXUNUSED(event)) {
    Close(TRUE);
  }

  void MyFrame::OnAbout(wxCommandEvent &WXUNUSED(event)) {
    wxMessageBox("This is a wxWindows Hello World sample",
                 "About Hello World", wxOK | wxICON_INFORMATION, this);
  }

File setab.f

Store the following code in the file 'setab.f':

      subroutine setab(a,b)
      integer a, b
      a=3;
      b=5;
      return
      end

Compilation Steps

Each program is compiled into an object file using the appropriate compiler with the -c flag. After all the object files are created, the final g++ command links the object files together into a single executable:

    mwr@ch208a:~/code/c++$ g++ -c hw-wx.C `wx-config --cxxflags`
    mwr@ch208a:~/code/c++$ g77 -c setab.f
    mwr@ch208m:~/code/c++$ g++ -o hw-wx-2 `wx-config --libs` hw-wx.o setab.o

Results

To run the program:

    mwr@ch208a:~/code/c++$ ./hw-wx-2

Hello, World screenshot

Filed under: , ,