For details, see How to Use.
Wrapping a C Program with a GUI (3: Building an App-Like Window)
This article shows how to call a C program from a GUI screen built with VCSSL, pass input values to it, and display the results on the screen.
In the previous article, the processing itself was the same, but the input and output methods were only very simple.
This time, as a more practical extension, we build a proper GUI application-style window so that values can be entered, the program can be run, and the results can be displayed there.
How to Use
Download and Extract
At first, click the "Download" button at the above of the title of this page by your PC (not smartphone). A ZIP file will be downloaded.
Then, please extract the ZIP file. On general environment (Windows®, major Linux distributions, etc.), you can extract the ZIP file by selecting "Extract All" and so on from right-clicking menu.
» If the extraction of the downloaded ZIP file is stopped with security warning messages...
Execute this Program
Next, open the extracted folder and execute this VCSSL program.
For Windows
Double-click the following batch file to execute:
For Linux, etc.
Execute "VCSSL.jar" on the command-line terminal as follows:
java -jar VCSSL.jar
» If the error message about non-availability of "java" command is output...
How to Operate After Launch
When you run this VCSSL program, an app-like window like the one below will appear (it is built using VCSSL's GUI features):
Enter the parameter values to pass to the C program into the three input fields at the top of the window.
Then, when you click the "Run" button, the C program program.exe is called and executed internally.
The first time you run it, the following security warning will appear. Click "Yes" to continue.
Note: The "run external program" operation covered here runs outside VCSSL's security monitoring scope, which means it can essentially do anything. That is what this warning is asking you to allow. Avoid clicking "Yes" casually for programs you do not trust.
Also, this message appears every time the program is run for the first time after startup. If that is annoying, you can disable it by checking "Security" > "Allow execution of system commands" from the VCSSL window menu.
After you continue, the contents printed by the C program to standard output will be displayed in the "Output" area at the bottom of the screen:
Content of argv[0]: C:\...(omitted)...\program.exe
Content of argv[1]: aaa
Content of argv[2]: bbbb
Content of argv[3]: ccccc
Also, the "Error" area shows whatever the C program printed to standard error. In this sample, it intentionally prints a dummy error message:
That is all for the basic operation and behavior.
The C source file program.c, from which program.exe was built, is also included, so feel free to modify it, recompile it, and experiment.
Topic Overview
It is common to want to call a program written in another language such as C from a lightweight scripting language like VCSSL.
A typical example is when building a small GUI tool:
- Write the user-facing screen in a scripting language
- Write complicated or heavy internal processing in C or a similar language
Following that theme, this series has been explaining how to implement a GUI application built in VCSSL that wraps a C program. So far:
- In the first article, we called a C program that simply displayed "Hello, World!" from VCSSL and captured its output.
- In the second article, we revised that example slightly and handled passing parameter values from VCSSL to the C program when running it.
And now, in this third article, we take the second example one step further and finally place a proper app-like GUI window on top of it.
The code in this article can be applied broadly to:
You will need to customize things such as the number of parameters, but you are free to modify and reuse it, so please try adapting it in your own projects.
When doing that kind of customization or reuse, the section near the end of this page titled:
may also be helpful. These days, AI can provide quite a bit of support.
Code Explanation
The main program is written in VCSSL. VCSSL uses a simple C-like syntax, so if you are used to C, you should be able to read and write it normally.
Also, this code is essentially an applied version of the code from the previous article. If you are not in a hurry, it will be easier to follow if you first read that article:
In addition, this article uses VCSSL's GUI features. There is an official guide for them below, so refer to it as needed:
Now, let's get into the code walkthrough.
Full Code
First, let's look at the complete VCSSL code:
-GUIWrapperWindow.vcssl -
coding UTF-8;
// Load required libraries
import GUI;
import File;
import Process;
// Declare global variables together for storing GUI component IDs
int window = NULL; // Window
int aField = NULL; // Input field for value A
int aLabel = NULL; // Label for value A
int bField = NULL; // Input field for value B
int bLabel = NULL; // Label for value B
int cField = NULL; // Input field for value C
int cLabel = NULL; // Label for value C
int runButton = NULL; // Run button
int outputArea = NULL; // Output display area
int outputLabel = NULL; // Label for the output area
int errorArea = NULL; // Error display area
int errorLabel = NULL; // Label for the error area
// Program execution starts here (entry point)
void main() {
// Build the GUI components and create the window
initGUI();
// Hide the VCSSL console (black window) because it is not used
hide();
// Startup processing ends here.
// Processing when the button is clicked starts from the
// onButtonClick event handler and reaches executeExternalProgram()
// near the end of this code.
}
// Function that builds the GUI components and creates the window
void initGUI() {
// Create the window
// Arguments: top-left X, Y, width, height, window title
window = newWindow(0, 0, 540, 530, "GUI Wrapper Window");
// Create and place the input field and label for value A
// Arguments: top-left X, Y, width, height, label text or default value
aLabel = newTextLabel(10, 10, 50, 30, "Value A:");
aField = newTextField(60, 10, 450, 30, "aaa");
mountComponent(aLabel, window);
mountComponent(aField, window);
// Create and place the input field and label for value B
bLabel = newTextLabel(10, 50, 50, 30, "Value B:");
bField = newTextField(60, 50, 450, 30, "bbbb");
mountComponent(bLabel, window);
mountComponent(bField, window);
// Create and place the input field and label for value C
cLabel = newTextLabel(10, 90, 50, 30, "Value C:");
cField = newTextField(60, 90, 450, 30, "ccccc");
mountComponent(cLabel, window);
mountComponent(cField, window);
// Create and place the Run button
runButton = newButton(10, 130, 500, 50, "Run");
mountComponent(runButton, window);
// Create and place the output display area and label
outputArea = newTextArea(10, 220, 500, 150, "");
outputLabel = newTextLabel(10, 200, 500, 20, "Output:");
mountComponent(outputArea, window);
mountComponent(outputLabel, window);
// Create and place the error display area and label
errorArea = newTextArea(10, 400, 500, 80, "");
errorLabel = newTextLabel(10, 380, 500, 20, "Error:");
mountComponent(errorArea, window);
mountComponent(errorLabel, window);
// Redraw the screen
paintComponent(window);
}
// Event handler function called when a button is pressed
void onButtonClick(int id, string text) {
// If the pressed button is the Run button, execute the program
if (id == runButton) {
executeExternalProgram();
}
// If there are other buttons as well, handle them in an if statement like above
}
// Execute the external C program "program.exe" using the values entered on the screen as parameters
void executeExternalProgram() {
// Get the absolute path of the C program file to execute
string programPath = getFilePath("program.exe");
// Prepare an array to store the command used to launch the C program
string commandWords[4];
// Put the absolute path of the program to run in the first element
commandWords[0] = programPath;
// The remaining elements are parameter values passed to the program, so get them from the screen
commandWords[1] = getComponentText(aField); // Input value A
commandWords[2] = getComponentText(bField); // Input value B
commandWords[3] = getComponentText(cField); // Input value C
// Prepare the program in an executable state (passing the command prepared above here)
int processID = newProcess(commandWords);
// If the program outputs Japanese or other multibyte text,
// specify character encoding to avoid garbled output
// (If this causes garbling instead, try specifying "UTF-8" and so on)
// ---
// setProcessInputEncoding(processID, "CP932");
// setProcessOutputEncoding(processID, "CP932");
// setProcessErrorEncoding(processID, "CP932");
// Run the program and wait for it to finish
startProcess(processID);
waitForProcess(processID);
// Get the program output and display it on the screen
string outputContent = getProcessOutput(processID);
setComponentText(outputArea, outputContent);
// Get the program error output and display it on the screen
string errorContent = getProcessError(processID);
setComponentText(errorArea, errorContent);
}
// Event handler function called when the window is closed
void onWindowClose(int id) {
// End execution of this VCSSL program
exit();
}
GUIWrapperWindow.vcssl
By the way, this code internally calls and runs a sample C program named program.exe (already compiled for Windows). Its source code is as follows:
program.c -
#include <stdio.h>
// The input values from VCSSL are passed in the argv arguments below
// Note: argv[0] contains the program name or path by C language convention
int main(int argc, char *argv[]) {
printf("-- Output from the C program --\n");
// Print all arguments to standard output
for (int iarg=0; iarg<argc; iarg++) {
printf("Content of argv[%d]: %s\n", iarg, argv[iarg]);
}
// Print a dummy error message
fprintf(stderr, "This is a dummy error message.");
}
program.c
When this C program is run directly, it simply prints the contents of argv passed to main.
For example, suppose you run it on the command line like this:
Then the output will be:
Content of argv[0]: C:\(...omitted...)\program.exe
Content of argv[1]: aaa
Content of argv[2]: bbbb
Content of argv[3]: ccccc
This is a dummy error message.
It is not a program with any practical purpose, but it is convenient for checking that values can be passed from VCSSL to a C program and received correctly. In other words, this is only a sample for that purpose.
Once you have confirmed that it works properly in your environment, feel free to replace it with a meaningful C program or rewrite it and reuse it as you like.
Importing Libraries
Now, returning to the VCSSL code, let's go through it from the top by picking out the important parts.
First, at the beginning, it declares that the code is written in the UTF-8 character encoding (to avoid misinterpretation), and then loads the required libraries:
coding UTF-8;
// Load required libraries
import GUI;
import File;
import Process;
import.txt
GUI is the library that provides the GUI-related features needed to build the screen in this article.
File is a library for obtaining and converting file paths. Here, it is used to get the absolute path of the program to execute.
Process is a library for executing and controlling external programs.
Global Variables for Storing GUI Component IDs
Next, let's look at the following part. Here, variables are declared to store the management numbers of the various components placed on the screen, called GUI component IDs:
// Declare global variables together for storing GUI component IDs
int window = NULL; // Window
int aField = NULL; // Input field for value A
int aLabel = NULL; // Label for value A
int bField = NULL; // Input field for value B
int bLabel = NULL; // Label for value B
int cField = NULL; // Input field for value C
int cLabel = NULL; // Label for value C
int runButton = NULL; // Run button
int outputArea = NULL; // Output display area
int outputLabel = NULL; // Label for the output area
int errorArea = NULL; // Error display area
int errorLabel = NULL; // Label for the error area
globalvar.txt
These IDs are issued in the next part, when the components are created. They are needed when placing those components and when setting or retrieving their values later.
Building the Window at Program Startup
Next.
In VCSSL, if you declare a main function, it is automatically called when program execution starts, just like in C.
In this article, the processing starting from that main function builds the GUI components and creates the window.
That said, if you write all of that directly inside main, the flow becomes harder to follow when the code grows. So it is separated into an initGUI function, and main simply calls it:
// Program execution starts here (entry point)
void main() {
// Build the GUI components and create the window
initGUI();
// Startup processing ends here.
// Processing when the button is clicked starts from the
// onButtonClick event handler and reaches executeExternalProgram()
// near the end of this code.
}
// Function that builds the GUI components and creates the window
void initGUI() {
// Create the window
// Arguments: top-left X, Y, width, height, window title
window = newWindow(0, 0, 540, 530, "GUI Wrapper Window");
// Create and place the input field and label for value A
// Arguments: top-left X, Y, width, height, label text or default value
aLabel = newTextLabel(10, 10, 50, 30, "Value A:");
aField = newTextField(60, 10, 450, 30, "aaa");
mountComponent(aLabel, window);
mountComponent(aField, window);
// Create and place the input field and label for value B
bLabel = newTextLabel(10, 50, 50, 30, "Value B:");
bField = newTextField(60, 50, 450, 30, "bbbb");
mountComponent(bLabel, window);
mountComponent(bField, window);
// Create and place the input field and label for value C
cLabel = newTextLabel(10, 90, 50, 30, "Value C:");
cField = newTextField(60, 90, 450, 30, "ccccc");
mountComponent(cLabel, window);
mountComponent(cField, window);
// Create and place the Run button
runButton = newButton(10, 130, 500, 50, "Run");
mountComponent(runButton, window);
// Create and place the output display area and label
outputArea = newTextArea(10, 220, 500, 150, "");
outputLabel = newTextLabel(10, 200, 500, 20, "Output:");
mountComponent(outputArea, window);
mountComponent(outputLabel, window);
// Create and place the error display area and label
errorArea = newTextArea(10, 400, 500, 80, "");
errorLabel = newTextLabel(10, 380, 500, 20, "Error:");
mountComponent(errorArea, window);
mountComponent(errorLabel, window);
// Redraw the screen
paintComponent(window);
}
create.txt
Inside the initGUI function that builds the screen, the code keeps creating and placing GUI components using new... functions one after another.
For a more detailed explanation of this part, please refer to the following section of the official guide:
That completes the flow executed from main at startup. After that, nothing happens until the user clicks the Run button.
What Happens When the Button Is Pressed
Next, let's move on to the flow triggered when the user clicks the Run button.
In VCSSL's GUI feature set, functions called event handler functions are automatically executed at such UI interaction timings.
Details are explained here:
To perform processing when the user clicks a button, as in this article, you declare an onButtonClick function and write the desired logic there:
// Event handler function called when a button is pressed
void onButtonClick(int id, string text) {
// If the pressed button is the Run button, execute the program
if (id == runButton) {
executeExternalProgram();
}
// If there are other buttons as well, handle them in an if statement like above
}
event.txt
This article only has one button, but if there are multiple buttons, the same onButtonClick function is executed no matter which one is pressed. The GUI component ID of the pressed button is passed in the argument id.
Therefore, a typical implementation is to branch by ID with if statements like above and describe the processing for each button.
Since the ID of this article's "Run" button is stored in the global variable runButton, the code above calls executeExternalProgram() (explained next) when that button is clicked.
Running the C Program
Next is the part that actually executes the C program, called from the event handler above. It is written as the executeExternalProgram function:
// Execute the external C program "program.exe" using the values entered on the screen as parameters
void executeExternalProgram() {
// Get the absolute path of the C program file to execute
string programPath = getFilePath("program.exe");
// Prepare an array to store the command used to launch the C program
string commandWords[4];
// Put the absolute path of the program to run in the first element
commandWords[0] = programPath;
// The remaining elements are parameter values passed to the program, so get them from the screen
commandWords[1] = getComponentText(aField); // Input value A
commandWords[2] = getComponentText(bField); // Input value B
commandWords[3] = getComponentText(cField); // Input value C
// Prepare the program in an executable state (passing the command prepared above here)
int processID = newProcess(commandWords);
// If the program outputs Japanese or other multibyte text,
// specify character encoding to avoid garbled output
// (If this causes garbling instead, try specifying "UTF-8" and so on)
// ---
// setProcessInputEncoding(processID, "CP932");
// setProcessOutputEncoding(processID, "CP932");
// setProcessErrorEncoding(processID, "CP932");
// Run the program and wait for it to finish
startProcess(processID);
waitForProcess(processID);
// Get the program output and display it on the screen
string outputContent = getProcessOutput(processID);
setComponentText(outputArea, outputContent);
// Get the program error output and display it on the screen
string errorContent = getProcessError(processID);
setComponentText(errorArea, errorContent);
}
execute.txt
Most of this function is just the code from the previous article wrapped in a function. So for details, please refer to the previous code walkthrough:
What differs from the previous article here is:
- The parameter values passed to the C program are obtained from text fields on the screen
(in the previous article, the user was asked with theinputfunction) - The output from the C program is set into text areas on the screen
(in the previous article, it was simply printed withprintln)
In the code, those correspond respectively to:
// The remaining elements are parameter values passed to the program, so get them from the screen
commandWords[1] = getComponentText(aField); // Input value A
commandWords[2] = getComponentText(bField); // Input value B
commandWords[3] = getComponentText(cField); // Input value C
input.txt
and:
// Get the program output and display it on the screen
string outputContent = getProcessOutput(processID);
setComponentText(outputArea, outputContent);
output.txt
Operations for getting and setting values on GUI components like this are explained in detail here:
In particular, setComponentText and getComponentText, which are used here, are functions you will use very often.
Cleanup When the Window Is Closed
Now we are at the end of the code for this article.
An event handler is defined so that when the custom GUI window is closed, execution of the VCSSL program also ends:
// Event handler function called when the window is closed
void onWindowClose(int id) {
// End execution of this VCSSL program
exit();
}
close.txt
Unless you explicitly implement termination like this in an event handler, simply closing the window does not end execution of the VCSSL program.
Especially in a case like this, where the VCSSL console is hidden, if you do not implement termination processing yourself as above, the program becomes troublesome because you would have no easy way to stop it except through Task Manager or similar tools.
Extension: Try Using AI for Projects Like This
That concludes the explanation of this article's code. Everything after this point is extra.
VCSSL Assistant: The Official VCSSL Support AI Running on ChatGPT
Processing like the initGUI function in this article, where you keep creating and placing a lot of GUI components, is not especially fun to write and is mostly just tedious and repetitive.
In such cases, it may be useful to take advantage of the official VCSSL support AI, VCSSL Assistant:
Because VCSSL Assistant runs on ChatGPT, it is easy to use.
Asking AI to Build a Screen from Scratch
As a test, let's ask AI to generate something equivalent to the initGUI function in this article:
(Prompt)
Please write the following GUI construction code as an initGUI function.
Thank you!
- There are three text fields labeled Value A, B, and C at the top of the screen
- Below them is a "Run" button
- Below that is a text area for displaying "Output" (with a label)
- Below that is a text area for displaying "Error" (with a label)
Then the AI produced the following code (using the model GPT-5.2 Thinking):
When this initGUI function was called and run, it built the following screen:
The layout is a little too spread out, but it is certainly usable. For a quick internal tool that only you will use, that is perfectly acceptable.
Asking AI to Modify the Code in This Article (Increase the Number of Inputs)
Here is another example: instead of asking AI to generate a screen from scratch, give it the full code from this article and ask it to modify that code so the number of parameters increases from three to five.
(Prompt)
Please modify the following code and increase the number of input values
from 3 to 5 (Values A through E).
Thank you!
---
(Insert the code from this article here)
The AI then produced the following code (again using GPT-5.2 Thinking):
When we ran it, it started without errors on the first try and displayed the following screen:
Now the layout is nicely arranged too. After also editing and testing the C program side, all five input values were passed correctly to program.exe.
That result was almost perfect, with a quality level comparable to code edited by a human.
In this way, AI tends to work quite well in situations like taking code that already has a reasonable foundation and modifying it. Humans are the same in that respect. It is probably easier because the existing code provides the overall tone and direction.
Other Things It Can Do, and Some Cautions
As shown above, VCSSL Assistant can already help quite a bit with tasks like modifying GUI code. Since those parts tend to be tedious for humans, it is worth taking advantage of it.
It can also read all of the VCSSL guides, so it is fairly good at answering questions. The same goes for the library specifications: if you ask about a specific function, it can often quote and explain the relevant parts.
However, when the program becomes difficult and long, mistakes and confusion still occur. Some are simple errors, while others are things like writing code that is syntactically invalid in VCSSL or using features that do not exist.
So for now, checking and manual debugging are still necessary. It is improving little by little every day, so please keep its current limitations in mind and use it with that understanding.
That is all for this article. In the next one, we will explain code that uses standard input to interact with a C program in a conversational way.
License
This VCSSL/Vnano code (files with the ".vcssl" or ".vnano" extensions) is released under the CC0 license, effectively placing it in the public domain. If any sample code in C, C++, or Java is included in this article, it is also released under the same terms. You are free to use, modify, or repurpose it as you wish.
* The distribution folder also includes the VCSSL runtime environment, so you can run the program immediately after downloading.
The license for the runtime is included in the gLicenseh folder.
(In short, it can be used freely for both commercial and non-commercial purposes, but the developers take no responsibility for any consequences arising from its use.)
For details on the files and licenses included in the distribution folder, please refer to "ReadMe.txt".
* The Vnano runtime environment is also available as open-source, so you can embed it in other software if needed. For more information, see here.










